Author Topic: Sniffing the Rigol's internal I2C bus  (Read 480562 times)

0 Members and 6 Guests are viewing this topic.

Offline zombie28

  • Regular Contributor
  • *
  • Posts: 69
Re: Sniffing the Rigol's internal I2C bus
« Reply #465 on: July 21, 2013, 10:53:06 AM »
Just to satisfy my curiosity, why the seed?  Does this imply there are 999999999 possible valid codes?  I've tried 3 different seeds and two did work while one did not...

ecsign in MIRACL contains a little buggy implementation of ECDSA - it doesn't check for cases that may require restart of the algorithm, so sometimes it can return invalid signature.

Offline DanielR

  • Contributor
  • Posts: 10
  • Country: au
Re: Sniffing the Rigol's internal I2C bus
« Reply #466 on: July 21, 2013, 12:54:26 PM »
So how do you actually generate the key for the scopes serial?

I have MIRACL and main.c compiled.

Regards
Daniel

Offline true

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: us
  • Squealing reasonably in the face of hypocrisy
Re: Sniffing the Rigol's internal I2C bus
« Reply #467 on: July 21, 2013, 12:56:19 PM »
Requires mapping the signed key (serial+opts) to the Rigol license format. It looks like docmandu has done this. I'm working on it now; hopefully someone will paste working code before me. Why not help work on it? Shouldn't take too long.

alan2k: can you stop posting if you are just going to erase the posts?

Offline BravoV

  • Super Contributor
  • ***
  • Posts: 3079
  • Country: 00
  • An EEE (Eternal Electronics Enthusiast)
Re: Sniffing the Rigol's internal I2C bus
« Reply #468 on: July 21, 2013, 01:03:36 PM »
alan2k: can you stop posting if you are just going to erase the posts?

+1, its so fucking annoying to read thru those junks in this really great thread :-- , ignore list updated.

Offline DanielR

  • Contributor
  • Posts: 10
  • Country: au
Re: Sniffing the Rigol's internal I2C bus
« Reply #469 on: July 21, 2013, 01:05:28 PM »
Requires mapping the signed key (serial+opts) to the Rigol license format. It looks like docmandu has done this. I'm working on it now; hopefully someone will paste working code before me. Why not help work on it? Shouldn't take too long.

alan2k: can you stop posting if you are just going to erase the posts?

Right, well I can certainly can help test with my scope if that helps. Ill keep an eye on this.
If there is some code to write I am pretty good in python, c not at all really.

Offline true

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: us
  • Squealing reasonably in the face of hypocrisy
Re: Sniffing the Rigol's internal I2C bus
« Reply #470 on: July 21, 2013, 01:13:20 PM »
Language doesn't matter

The only references I have is the rigol-to-hex mapping function in main.c, the valid character list, and some valid mapped keys as listed in this thread

edit: mostly done, I think I still have a bug, but I can't generate to test...same issue that I thought I read before (did alank2 delete it? he ruins the discussion), where seed does vary what I see in signed.ecs.

edit 2: don't know what I did while playing with it, now I can generate the sample listed here.

edit 3: hexkey to rigol key done. but ecsign still doesn't work for any other key/serial other than the demo posted earlier, with the seed posted earlier...
« Last Edit: July 21, 2013, 07:38:37 PM by true »

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 236
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #471 on: July 21, 2013, 08:07:38 PM »
cool stuff, i have a tool that can generate key strings, will release shortly.
i must admit i got the private key yesterday via mail from a guy already, but my ecs tools where so heavily "recoded", the just outputted crap ;-)

should have something this night (GMT) ;-)
___________________
"all rights reversed :-)"
R0=-0x18;
UNLINK;
RTS;

Offline UberSteve

  • Contributor
  • Posts: 20
  • Country: au
Re: Sniffing the Rigol's internal I2C bus
« Reply #472 on: July 21, 2013, 08:10:03 PM »
Keeping a very close eye on this thread....very exciting! Great work guys!  :clap:  :-+

Offline true

  • Frequent Contributor
  • **
  • Posts: 252
  • Country: us
  • Squealing reasonably in the face of hypocrisy
Re: Sniffing the Rigol's internal I2C bus
« Reply #473 on: July 21, 2013, 08:15:11 PM »
alright, I found the bug... still not sure what it is, something with how the file is edited... echo -n 'DS2A123456789XXXX' > lic works...

So now I can generate license code strings.

Code: [Select]
$ echo -n "DS2A123456873VSA9" > lic; echo -e "123879325\nlic\n" | ./ecsign | php gen.php; ./riglol `php gen.php`
MVVD4QW-CSSG5HS-GMAAMER-J3VS9L4 DS2A123456873

serial:           DS2A123456873
license-key:      MVVD4QWCSSG5HSGMAAMERJ3VS9L4
license-skipped:  MVD4QWCSG5HSGMAMERJ3VSL4 (5CC7A7505036CF032C0B23D199C15)
license-1-mapped: 5CC7A7505036CF
license-2-mapped: 32C0B23D199C15
license-options:  VSA9 (9C01)
serial&options:   DS2A123456873VSA9
sha1(serial&opts) D3B9717C00057C72EDFD409F62F2F10EE04135F2

v:    5CC7A7505036CF
lic1: 5CC7A7505036CF

 License Key is VALID

Questions for others investigating:
1. Is VSA9 the only code that should / can be used? Other codes don't seem to generate valid keys.
2. I generated a key for my scope that passed riglol, but it didn't work (License is unavailable! error) :( Should I try different seeds since the codes change?
« Last Edit: July 21, 2013, 08:17:16 PM by true »

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 236
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #474 on: July 21, 2013, 09:11:52 PM »
enjoy ! - now i can finaly put by scope back together ;-)  :-+

UPDATE: for a DS2000 use DSA9 as option key !

Code: [Select]
/*
** rigol ds2000 keygen / cybernet & the-eevblog-users
**
** to compile this you need MIRACL from [url]https://github.com/CertiVox/MIRACL[/url]
** download the master.zip into a new folder and run 'unzip -j -aa -L master.zip'
** then run 'bash linux' to build the miracle.a library
**
** BUILD WITH:
**
** gcc rikey.c -I../MIRACL ../MIRACL/miracl.a -o rikey
**
** adapt -I and path to miracl.a to your environment
**
** more info: http://www.eevblog.com/forum/testgear/sniffing-the-rigol's-internal-i2c-bus/
**
** then fetch private key from EEV Blog and put into "private_key[]=" below, do not prefix with 0x
** supply your serial and wanted options, and enjoy !
**
**
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "miracl.h"

#define RIGOL_DS2000

// START OF SETTINGS FOR ECC
#ifdef RIGOL_DS2000
 unsigned char private_key[]="8.....";   // <- RILOL FILL ME (no 0x prefix !)
 unsigned char prime1[]="AEBF94CEE3E707";
 unsigned char prime2[]="AEBF94D5C6AA71";
 unsigned char curve_a[]="2982";
 unsigned char curve_b[]="3408";
 unsigned char point1[]="7A3E808599A525";
 unsigned char point2[]="28BE7FAFD2A052";
#endif
// END OF SETTINGS FOR ECC

unsigned char codemap_ee00d0[]={ 0x0, 0x0, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
                                 0x0, 0x0, 0x0,  0x0,  0x0,  0x0,  0x0,  0x0,  0x1,  0x2,
                                 0x3, 0x4, 0x5,  0x6,  0x7,  0x0,  0x8,  0x9,  0xa,  0xb,
                                 0xc, 0x0, 0xd,  0xe,  0xf,  0x10, 0x11, 0x12, 0x13, 0x14,
                                 0x15,0x16, 0x17 };

unsigned char codemap_20688e[]={ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,  /* 0-9 = 0x30 */
                                 0x37, 0x37, 0x37, 0x37, 0x37, 0x37 };                        /* A-F = 0x37 */


unsigned char vb[]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9'};

void show_help(void)
{
 printf("./rikey <DSA2XXXXXXXXX> <OPTS>\n\n");
 printf("<DSA2XXXXXXXXX> -  serial number of device\n");
 printf("<OPTS> - \n");
 printf("\t\tDSA? for permanent options\n");
 printf("\t\tVSA? for temporary options\n");
 printf("\n\n");
}
/*
** take serial and options make sha1 hash out of it
*/
static void hashing(unsigned char *opt_str,big hash)
{ /* compute hash function */
    char *p;
    char h[20];
    int ch;
    sha sh;
    shs_init(&sh);
    p=opt_str;
    while(*p)
    {
       shs_process(&sh,*p);
       p++;
    }
    shs_hash(&sh,h);
    bytes_to_big(20,h,hash);
}
/*
** sign the secret message (serial + opts) with the private key
*/
int ecssign(unsigned char *serial, unsigned char *opt, unsigned char *lic1, unsigned char *lic2)
{
    FILE *fp;
    char ifname[50],ofname[50];
    big a,b,p,q,x,y,d,r,s,k,hash;
    epoint *g;
    long seed;
    int bits;
    miracl *mip;
    unsigned char *serial_options;

/* get public data */
    mip=mirsys(0x320, 0x10);   /* Use Hex internally */
    mip->IOBASE=16;
    a=mirvar(0);
    b=mirvar(0);
    p=mirvar(0);
    q=mirvar(0);
    x=mirvar(0);
    y=mirvar(0);
    d=mirvar(0);
    r=mirvar(0);
    s=mirvar(0);
    k=mirvar(0);
    hash=mirvar(0);

    instr(p,prime1);     /* modulus        */
    instr(a,curve_a);     /* curve parameters */
    instr(b,curve_b);
    instr(q,prime2);     /* order of (x,y) */
    instr(x,point1);     /* (x,y) point on curve of order q */
    instr(y,point2);

/* randomise */
    seed=1;
    irand(seed);

    ecurve_init(a,b,p,MR_PROJECTIVE);  /* initialise curve */
    g=epoint_init();

    if (!epoint_set(x,y,0,g)) /* initialise point of order q */
    {
        printf("1. Problem - point (x,y) is not on the curve\n");
        exit(0);
    }

/* calculate r - this can be done offline,
   and hence amortized to almost nothing   */
    bigrand(q,k);
    ecurve_mult(k,g,g);      /* see ebrick.c for method to speed this up */
    epoint_get(g,r,r);
    divide(r,q,q);

/* get private key of signer */
    instr(d, private_key);

/* calculate message digest */
    serial_options=calloc(128,1);
    strcpy(serial_options, serial);
    strcat(serial_options, opt);
    hashing(serial_options,hash);

/* calculate s */
    xgcd(k,q,k,k,k);
    mad(d,r,hash,q,q,s);
    mad(s,k,k,q,q,s);

    cotstr(r,lic1);
    cotstr(s,lic2);
    return 0;
}


/*
** convert string to uppercase chars
*/
unsigned char *strtoupper(unsigned char *str)
{
    unsigned char *newstr, *p;
    p = newstr = (unsigned char*) strdup((char*)str);
    while((*p++=toupper(*p)));
    return newstr;
}

/*
**
*/
unsigned char code_map_206846(unsigned char i)
{
 if ((i >= 'A') && (i <= 'F')) return(i-0x37);
 if ((i >= '0') && (i <= '9')) return(i-0x30);
 return(0x0);
}

/*
** Encryption Routine 1
*/
unsigned char *lic_code_map(unsigned char *lic_skipped)
{
 unsigned char lv1,lv2;
 unsigned char b1_mapped, b1_shifted, b1_remapped;
 unsigned char b2_mapped, b2_shifted, b2_remapped;
 unsigned char b3_mapped, b3_shifted, b3_remapped;
 unsigned char b4_mapped, b4_shifted, b4_remapped;
 unsigned char b5_shifted, b5_remapped;
 unsigned char *lic_mapbytes;

 lic_mapbytes=calloc(28, 1);
 if (!lic_mapbytes) return(0);
lv1=lv2=0;
 while(lv1 < strlen((unsigned char*)lic_skipped))
 {
    b1_mapped =  codemap_ee00d0[ *(lic_skipped+lv1) - 0x30 ];
    b1_shifted = (b1_mapped / 2) & 0xf;
    b1_remapped = b1_shifted + codemap_20688e[b1_shifted];
    lic_mapbytes[lv2++]=b1_remapped;
    b1_mapped = b1_mapped & 0x1;

    b2_mapped =  codemap_ee00d0[ *(lic_skipped+lv1+1) - 0x30 ];
    b2_shifted =  ((b1_mapped << 0x3) | (b2_mapped / 4)) & 0xF;
    b2_remapped = b2_shifted + codemap_20688e[b2_shifted];
    lic_mapbytes[lv2++]=b2_remapped;

    b3_mapped = codemap_ee00d0[ *(lic_skipped+lv1+2) - 0x30 ];
    b3_shifted = ((b3_mapped / 8) | ( (b2_mapped & 0x3) << 2 )) & 0xF;
    b3_remapped = b3_shifted + codemap_20688e[b3_shifted];
    lic_mapbytes[lv2++]=b3_remapped;

    b4_mapped = codemap_ee00d0[ *(lic_skipped+lv1+3) - 0x30 ];
    b4_shifted = ((b4_mapped / 16 ) |((b3_mapped & 0x7) << 0x1)) & 0xf;
    b4_remapped = b4_shifted + codemap_20688e[b4_shifted];
    lic_mapbytes[lv2++]=b4_remapped;

    b5_shifted = b4_mapped & 0xF;
    b5_remapped = b5_shifted + codemap_20688e[b5_shifted];
    lic_mapbytes[lv2++]=b5_remapped;

    lv1 = lv1 + 4;
  }
  return(lic_mapbytes);
}

unsigned char * find_match5(unsigned char *code5)
{
  unsigned char c1,c2,c3,c4;
  unsigned char *input;
  unsigned char *lic_mapbytes;
  input=calloc(40,1);

  /* lets bruteforce it ;-) */
  for (c1=0;c1<sizeof(vb);c1++) {
   for (c2=0;c2<sizeof(vb);c2++) {
    for (c3=0;c3<sizeof(vb);c3++) {
     for (c4=0;c4<sizeof(vb);c4++) {
      input[0]=vb[c1];
      input[1]=vb[c2];
      input[2]=vb[c3];
      input[3]=vb[c4];
      input[4]='\0';
      lic_mapbytes=lic_code_map(input);
      if (!strcmp(lic_mapbytes, code5))
      {
           return(input);
      }
     }
    }
   }
  }
  return(0); // no match
}

int main(int argc, char *argv[0])
{
 unsigned char *options,*lic1_code, *lic2_code, *lic_all;
 unsigned char *out,*chunk,*temp,*final;
 unsigned char *lic1_key, *lic2_key;
 unsigned char *serial;
 int            v,i=0;

 if (strlen(private_key)<14)
 {
  printf("\n\n");
  printf("set the private_key variable on top of this file\n");
  printf("you can find it here: http://www.eevblog.com/forum/testgear/sniffing-the-rigol's-internal-i2c-bus/msg264690/#msg264690\n");
  printf("\n\n");
  exit(-1);
 }

 if (argc != 3)
 {
  show_help();
  exit(-1);
 }
 serial=strtoupper((unsigned char*)argv[1]);
 options=strtoupper((unsigned char*)argv[2]);
 if (strlen(serial)<13)
 {
   printf("\nINVALID SERIAL LENGTH\n");
   show_help();
   exit(-1);
 }
 if (strlen(options)!=4)
 {
   printf("\nINVALID OPTIONS LENGTH\n");
   show_help();
   exit(-1);
 }
printf("serial:           %s\n", serial);
 printf("options:          %s\n", options);
 /* sign the message */
 lic1_code=calloc(64,1);
 lic2_code=calloc(64,1);
 ecssign(serial,options,lic1_code, lic2_code);
 printf("lic1-code:        %s\n", lic1_code);
 printf("lic2-code:        %s\n", lic2_code);

 lic_all=calloc(128,1);
 temp=calloc(128,1);
 chunk=calloc(6,1);
 final=calloc(128,1);
 lic1_key=calloc(20,1);
 lic2_key=calloc(20,1);
 strcpy(lic_all, lic1_code);
 strcat(lic_all, "0");
 strcat(lic_all, lic2_code);
 printf("target-code:      %s\n", lic_all);

 // split in 5 byte groups and run bruteforce
 // run or lic1_code
 strcat(lic1_code,"0");
 while(i<=strlen(lic1_code))
 {
   memcpy(chunk,lic1_code+i,5);
   out=find_match5(chunk);
   if (out)
   {
    strcat(temp, out);
   }
   i=i+5;
 }
 strcpy(lic1_key, temp);

 // run for lic2_code
 strcpy(temp,"");
 i=0;
 while(i<strlen(lic2_code))
 {
   memcpy(chunk,lic2_code+i,5);
   if (strlen(chunk)<5)
   {
    for(v=0;v<5-strlen(chunk);v++)
     strcat(chunk,"0");
   }
   out=find_match5(chunk);
   if (out)
   {
    strcat(temp, out);
   }
   i=i+5;
 }
strcpy(lic2_key, temp);
 strcpy(temp, lic1_key);
 strcat(temp, lic2_key);
 // now add the options
 memcpy(final, temp, 1);
 final[1]=options[0];
 memcpy(final+2, temp+1,7);
 final[9]=options[1];
 memcpy(final+10, temp+8,7);
 final[17]=options[2];
 memcpy(final+18, temp+15,7);
 final[25]=options[3];
 memcpy(final+26, temp+22,4);
 printf("----------------------------------------------------\n");
 printf("your-license-key: ");
 for(i=0;i<strlen(final);i++)
 {
  if (i%7==0 && i>0) printf("-");
  printf("%c", final[i]);
 }
 printf("\n");
 printf("----------------------------------------------------\n");
}
« Last Edit: July 21, 2013, 11:46:31 PM by cybernet »
___________________
"all rights reversed :-)"
R0=-0x18;
UNLINK;
RTS;

Offline BravoV

  • Super Contributor
  • ***
  • Posts: 3079
  • Country: 00
  • An EEE (Eternal Electronics Enthusiast)
Re: Sniffing the Rigol's internal I2C bus
« Reply #475 on: July 21, 2013, 10:04:13 PM »
You guys are awesome , big thank you !   :-+  :-+  :-+  :clap:

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 236
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #476 on: July 21, 2013, 10:05:23 PM »
there is some bug, working in it ... so hold your breath for now ;-)

bug fixed. SERIAL is 14 chars not 13 .. i corrected that - and one word of caution, my SERIAL number has just reverted to DS2A0...1 after playing with FW up/down grades
i give a f*ck - but be carefull ;-)

tested with FW05 and FW02 - works.
as long as you can spot the common.ecs parameters in the firmware (aka riglol.c) it should be fine.

some DS4 user should give it a try and report ;-)
« Last Edit: July 21, 2013, 10:31:08 PM by cybernet »
___________________
"all rights reversed :-)"
R0=-0x18;
UNLINK;
RTS;

Offline Carrington

  • Frequent Contributor
  • **
  • Posts: 964
  • Country: es
Re: Sniffing the Rigol's internal I2C bus
« Reply #477 on: July 21, 2013, 10:15:32 PM »
Amazing, very well done!  :)

Has anyone tried to Sniffing the Rigol's internal SPI bus of the LMH6518 to see if it works at 350MHz, or 200MHz?
Cheers.
Space Weather (NOAA): Alerts and Warnings.
DECO APP: To detect muons with your cell phone.

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 236
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #478 on: July 21, 2013, 10:25:16 PM »
suggest you read the WHOLE thread, your answers are there.
___________________
"all rights reversed :-)"
R0=-0x18;
UNLINK;
RTS;

Offline docmandu

  • Contributor
  • Posts: 17
Re: Sniffing the Rigol's internal I2C bus
« Reply #479 on: July 21, 2013, 10:26:03 PM »
Not at home atm‚ so excuse my terseness.

cybernet, you don't need to brute force to go back to serial format. look at my first post in this thread for the algo.

just need to take 5 bits at a time and convert them back to a character.


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf