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

rhost, alexwhittemore and 11 Guests are viewing this topic.

Offline true

  • Regular Contributor
  • *
  • Posts: 171
  • Country: us
Re: Sniffing the Rigol's internal I2C bus
« Reply #480 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: 229
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #481 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 #482 on: July 21, 2013, 08:10:03 PM »
Keeping a very close eye on this thread....very exciting! Great work guys!  :clap:  :-+

Offline true

  • Regular Contributor
  • *
  • Posts: 171
  • Country: us
Re: Sniffing the Rigol's internal I2C bus
« Reply #483 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: 229
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #484 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: 2918
  • Country: 00
  • An EEE (Eternal Electronics Enthusiast)
Re: Sniffing the Rigol's internal I2C bus
« Reply #485 on: July 21, 2013, 10:04:13 PM »
You guys are awesome , big thank you !   :-+  :-+  :-+  :clap:

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 229
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #486 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: 854
  • Country: es
Re: Sniffing the Rigol's internal I2C bus
« Reply #487 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.

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 229
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #488 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 #489 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.

Offline cybernet

  • Regular Contributor
  • *
  • Posts: 229
  • Country: 00
  • pm deactivated, use the search function ...
Re: Sniffing the Rigol's internal I2C bus
« Reply #490 on: July 21, 2013, 10:28:11 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.

true, but i thought its a tiny bit cooler, if it actually bruteforces SOMETHING in the process ;-)
im sure some windows guys will do a nice .exe for that .. they can do it more elegant then ..  :-DD
___________________
"all rights reversed :-)"
R0=-0x18;
UNLINK;
RTS;

Offline DanielR

  • Contributor
  • Posts: 8
  • Country: au
Re: Sniffing the Rigol's internal I2C bus
« Reply #491 on: July 21, 2013, 10:28:36 PM »
Works for me on latest firmware on a 2102.

Offline Carrington

  • Frequent Contributor
  • **
  • Posts: 854
  • Country: es
Re: Sniffing the Rigol's internal I2C bus
« Reply #492 on: July 21, 2013, 10:34:25 PM »
suggest you read the WHOLE thread, your answers are there.

Okay, so I will.
Thank you very much.  :)

Offline UberSteve

  • Contributor
  • Posts: 20
  • Country: au
Re: Sniffing the Rigol's internal I2C bus
« Reply #493 on: July 21, 2013, 10:36:21 PM »
enjoy ! - now i can finaly put by scope back together ;-)  :-+

Big thanks to all involved!  :-+

I can confirm it worked on my recently purchased DS2072 (shipped with latest 01.01.00.02 fw), using DSAZ. I also had ~1900 minutes on the trials remaining at the time of entering the key. It's now a DS2202 with all options "offcial version" ;D

Edit: Also restarted the scope several times just to make sure the options stuck!

« Last Edit: July 21, 2013, 10:38:06 PM by UberSteve »

Offline Chet T16

  • Supporter
  • ****
  • Posts: 511
  • Country: ie
    • Retro-Renault
Re: Sniffing the Rigol's internal I2C bus
« Reply #494 on: July 21, 2013, 10:54:39 PM »
Bah, can't get MIRACL to build with cygwin.

Someone make a windows executable. With installer. And an android app  :blah:
Chet
www.chet.ie - projects/electronics blog
BSc Engineering Science - Electronics
Studying ME Computer and Electronics


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf