SHARE
TWEET

rigolkey.c

a guest Jul 24th, 2013 5,034 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ** rigol ds2000 keygen / cybernet & the-eevblog-users
  3. **
  4. ** to compile this you need MIRACL from https://github.com/CertiVox/MIRACL
  5. ** download the master.zip into a new folder and run
  6. **
  7. **    unzip -j -aa -L master.zip
  8. **
  9. ** then run
  10. **
  11. **    bash linux
  12. **
  13. ** to build the 32-bit miracle.a library
  14. **
  15. ** then optionally fetch private key from EEVBlog and put into "private_key[]="
  16. ** below, do not prefix with 0x. excluding here will require the key at runtime.
  17. **
  18. **
  19. ** BUILD WITH:
  20. **    gcc rikey.c -m32 -I./MIRACL ./MIRACL/miracl.a -o rikey
  21. **
  22. ** adapt -I and path to miracl.a to your environment
  23. **
  24. ** more info: http://www.eevblog.com/forum/testgear/sniffing-the-rigol's-internal-i2c-bus/
  25. **
  26. ** run, supply your serial and wanted options, and enjoy!
  27. **
  28. ** tabs: 4 cols: 100 rev: 20130723_1_true
  29. **
  30. ** additions and changes:
  31. **   change: removed unused functions
  32. **   change: run-time private key option
  33. **   change: ecssign function clean-up (zombie28)
  34. **   fix: code is beautified
  35. **   fix: licenses are padded properly (Maalobs, true)
  36. **   fix: lic2 prime check (anonymous, cybernet, studio25)
  37. **   fix: unnecessary brute-force removed (studio25)
  38. */
  39.  
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <unistd.h>
  43. #include <string.h>
  44. #include <ctype.h>
  45. #include <stdio.h>
  46. #include "miracl.h"
  47.  
  48. #define RIGOL_DS2000
  49.  
  50. // START OF SETTINGS FOR ECC
  51. #ifdef RIGOL_DS2000
  52. unsigned char private_key[] = "8EEBD4D04C3771";         // fill me in (optional), B....
  53.  
  54. int           k_offset = 0;             // optionally change ecssign starting offset
  55.                                                                         // (changes lic1; makes different licenses)
  56. /* do not change these */
  57. unsigned char prime1[]  = "AEBF94CEE3E707";
  58. unsigned char prime2[]  = "AEBF94D5C6AA71";
  59. unsigned char curve_a[] = "2982";
  60. unsigned char curve_b[] = "3408";
  61. unsigned char point1[]  = "7A3E808599A525";
  62. unsigned char point2[]  = "28BE7FAFD2A052";
  63. #endif
  64. // END OF SETTINGS FOR ECC
  65.  
  66. unsigned char vb[] = {
  67.         'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
  68.         'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R',
  69.         'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
  70.         '2', '3', '4', '5', '6', '7', '8', '9'
  71. };
  72.  
  73. /*
  74. ** program help
  75. */
  76. void show_help(char *cmd)
  77. {
  78.         char text_pk[10];
  79.         strcpy(text_pk, strlen(private_key) ? "[privkey]" : "<privkey>");
  80.        
  81.         printf("\nUsage: %s <sn> <opts> %s\n\n", cmd, text_pk);
  82.         printf("  <sn>       serial number of device (DS2A.........)\n");
  83.         printf("  <opts>     device options, 4 characters, see below\n");
  84.         printf("  %s  private key%s\n\n\n", text_pk, strlen(private_key) ? " (optional)" : "");
  85.        
  86.         printf("device options:\n\n");
  87.         printf("  first character:  D = official, V = trial\n");
  88.         printf("  second character: S\n");
  89.         printf("  third character:  A = DS2000, H = DS4000\n");
  90.         printf("  last character :  your options, use the following table to generate for DS2000:\n\n");
  91.  
  92.         printf("  --------- 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\n");
  93.         printf("  100MHz    ' ' ' ' ' ' ' ' * * * * * * * * ' ' ' ' ' ' ' ' * * * * * * * *\n");
  94.         printf("  200MHz    ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' * * * * * * * * * * * * * * * *\n");
  95.         printf("  Memory56M ' ' ' ' * * * * ' ' ' ' * * * * ' ' ' ' * * * * ' ' ' ' * * * *\n");
  96.         printf("  Decode    ' ' * * ' ' * * ' ' * * ' ' * * ' ' * * ' ' * * ' ' * * ' ' * *\n");
  97.         printf("  Triggers  ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' * ' *\n\n");
  98.         printf("  For DS4000, try DSH9, VSH9 to enable all options.\n\n");
  99.         printf("MAKE SURE YOUR FIRMWARE IS UP TO DATE BEFORE APPLYING ANY KEYS\n\n");
  100. }
  101.  
  102. /*
  103. ** take serial and options make sha1 hash out of it
  104. */
  105. static void hashing(unsigned char *opt_str, big hash)
  106. {
  107.         char *p;
  108.         char h[20];
  109.         int ch;
  110.         sha sh;
  111.         shs_init(&sh);
  112.         p = opt_str;
  113.  
  114.         while(*p) {
  115.                 shs_process(&sh, *p);
  116.                 p++;
  117.         }
  118.    
  119.     shs_hash(&sh, h);
  120.     bytes_to_big(20, h, hash);
  121. }
  122.  
  123. /*
  124. ** sign the secret message (serial + opts) with the private key
  125. */
  126. void ecssign(char *serial, char *options, char *privk, char *lic1, char *lic2)
  127. {
  128.     mirsys(800, 16)->IOBASE = 16;
  129.  
  130.     sha sha1;
  131.     shs_init(&sha1);
  132.        
  133.     char *ptr = serial;
  134.     while(*ptr) shs_process(&sha1, *ptr++);
  135.     ptr = options;
  136.     while(*ptr) shs_process(&sha1, *ptr++);
  137.    
  138.         char h[20];
  139.     shs_hash(&sha1, h);
  140.     big hash = mirvar(0);
  141.     bytes_to_big(20, h, hash);
  142.  
  143.     big a = mirvar(0);  instr(a, curve_a);
  144.     big b = mirvar(0);  instr(b, curve_b);
  145.     big p = mirvar(0);  instr(p, prime1);
  146.     big q = mirvar(0);  instr(q, prime2);
  147.     big Gx = mirvar(0); instr(Gx, point1);
  148.     big Gy = mirvar(0); instr(Gy, point2);
  149.     big d = mirvar(0);  instr(d, privk);
  150.     big k = mirvar(0);
  151.     big r = mirvar(0);
  152.     big s = mirvar(0);
  153.     big k1 = mirvar(0);
  154.     big zero = mirvar(0);
  155.  
  156.     big f1 = mirvar(17);
  157.     big f2 = mirvar(53);
  158.     big f3 = mirvar(905461);
  159.     big f4 = mirvar(60291817);
  160.        
  161.         incr(k, k_offset, k);
  162.  
  163.     epoint *G = epoint_init();
  164.     epoint *kG = epoint_init();
  165.     ecurve_init(a, b, p, MR_PROJECTIVE);
  166.     epoint_set(Gx, Gy, 0, G);
  167.  
  168.     for(;;) {
  169.         incr(k, 1, k);
  170.  
  171.         if(divisible(k, f1) || divisible(k, f2) || divisible(k, f3) || divisible(k, f4))
  172.                         continue;
  173.  
  174.         ecurve_mult(k, G, kG);
  175.         epoint_get(kG, r, r);
  176.         divide(r, q, q);
  177.        
  178.         if(mr_compare(r, zero) == 0)
  179.             continue;
  180.  
  181.         xgcd(k, q, k1, k1, k1);
  182.         mad(d, r, hash, q, q, s);
  183.         mad(s, k1, k1, q, q, s);
  184.  
  185.         if(!divisible(s, f1) && !divisible(s, f2) && !divisible(s, f3) && !divisible(s, f4))
  186.             break;
  187.     }
  188.  
  189.     cotstr(r, lic1);
  190.     cotstr(s, lic2);
  191. }
  192.  
  193. /*
  194. ** convert string to uppercase chars
  195. */
  196. unsigned char * strtoupper(unsigned char *str)
  197. {
  198.         unsigned char *newstr, *p;
  199.         p = newstr = (unsigned char*) strdup((char*)str);
  200.         while ((*p++ = toupper(*p)));
  201.         return newstr;
  202. }
  203.  
  204. /*
  205. ** prepend a char to a string
  206. */
  207. unsigned char * prepend(unsigned char *c, unsigned char *str)
  208. {
  209.     int i;
  210.  
  211.     for (i = strlen(str); i >= 0; i--) {
  212.                 str[i + 1] = str[i];
  213.         }
  214.    
  215.     str[0] = *c;
  216.         return c;
  217. }
  218.  
  219. /*
  220. ** convert hex-ascii-string to rigol license format
  221. */
  222. unsigned char * map_hex_to_rigol(unsigned char *code5)
  223. {
  224.         unsigned long long b = 0;
  225.         unsigned char *out;
  226.         int i = 0;
  227.        
  228.         out = calloc(5, 1);
  229.  
  230.         /* hex2dez */
  231.         while (code5[i] != '\0') {
  232.                 if (code5[i] >= '0' && code5[i] <= '9') {
  233.                         b = b * 16 + code5[i] - '0';
  234.                 } else if (code5[i] >= 'A' && code5[i] <= 'F') {
  235.                         b = b * 16 + code5[i] - 'A' + 10;
  236.                 } else if (code5[i] >= 'a' && code5[i] <= 'f') {
  237.                         b = b * 16 + code5[i] - 'a' + 10;
  238.                 }
  239.        
  240.                 i++;
  241.         }    
  242.  
  243.         for (i = 3; ; i--) {
  244.                 out[i] = vb[b & 0x1F];
  245.                 if (i == 0) break;
  246.                 b >>= 5;
  247.         }
  248.  
  249.         out[4] = '\0';
  250.         return(out);
  251. }
  252.  
  253. /*
  254. ** the world ends here
  255. */
  256. int main(int argc, char *argv[0])
  257. {
  258.         unsigned char *options, *lic1_code, *lic2_code, *lic_all;
  259.         unsigned char *out, *chunk, *temp, *final;
  260.         unsigned char *lic1_key, *lic2_key, *priv_key;
  261.         unsigned char *serial;
  262.         int            i = 0, j = 0;
  263.  
  264.         if (!((argc == 3 && strlen(private_key)) || argc == 4)) {
  265.                 show_help(argv[0]);
  266.                 exit(-1);
  267.         }
  268.        
  269.         serial = strtoupper((unsigned char*)argv[1]);
  270.         options = strtoupper((unsigned char*)argv[2]);
  271.        
  272.         if (argc == 4) {
  273.                 priv_key = strtoupper((unsigned char*)argv[3]);
  274.         } else {
  275.                 priv_key = strtoupper((unsigned char*)private_key);    
  276.         }
  277.  
  278.         if (strlen(priv_key) != 14) {
  279.                 printf("\nERROR: INVALID PRIVATE KEY LENGTH\n");
  280.                 show_help(argv[0]);
  281.                 exit(-1);
  282.         }
  283.        
  284.         if (strlen(serial) < 13) {
  285.                 printf("\nERROR: INVALID SERIAL LENGTH\n");
  286.                 show_help(argv[0]);
  287.                 exit(-1);
  288.         }
  289.  
  290.         if (strlen(options) != 4) {
  291.                 printf("\nERROR: INVALID OPTIONS LENGTH\n");
  292.                 show_help(argv[0]);
  293.                 exit(-1);
  294.         }
  295.        
  296.         printf("private-key:      %s\n", priv_key);
  297.         printf("serial:           %s\n", serial);
  298.         printf("options:          %s\n", options);
  299.  
  300.         /* sign the message */
  301.         lic1_code = calloc(64, 1);
  302.         lic2_code = calloc(64, 1);
  303.        
  304.         ecssign(serial, options, priv_key, lic1_code, lic2_code);
  305.                
  306.         /* fix missing zeroes */
  307.         while (strlen(lic1_code) < 14) {
  308.                 prepend("0", lic1_code);
  309.         }
  310.         while (strlen(lic2_code) < 14) {
  311.                 prepend("0", lic2_code);
  312.         }
  313.        
  314.         printf("lic1-code:        %s\n", lic1_code);
  315.         printf("lic2-code:        %s\n", lic2_code);
  316.  
  317.         lic_all = calloc(128, 1);
  318.         temp = calloc(128, 1);
  319.         chunk = calloc(6, 1);
  320.         final = calloc(128, 1);
  321.         lic1_key = calloc(20, 1);
  322.         lic2_key = calloc(20, 1);
  323.        
  324.         strcpy(lic_all, lic1_code);
  325.         strcat(lic_all, "0");
  326.         strcat(lic_all, lic2_code);
  327.         printf("target-code:      %s\n", lic_all);
  328.  
  329.         strcat(lic1_code, "0");
  330.        
  331.         while (i < strlen(lic1_code)) {
  332.                 memcpy(chunk, lic1_code + i, 5);
  333.                 out = map_hex_to_rigol(chunk);
  334.        
  335.                 if (out) {
  336.                         strcat(temp, out);
  337.                 }
  338.    
  339.                 i = i + 5;
  340.         }
  341.  
  342.         strcpy(lic1_key, temp);
  343.  
  344.         // run for lic2_code
  345.         strcpy(temp, "");
  346.        
  347.         i = 0;
  348.         while (i < strlen(lic2_code)) {
  349.                 memcpy(chunk, lic2_code + i, 5);
  350.                
  351.                 if (strlen(chunk) < 5) {
  352.                         for(j = 0; j < 5 - strlen(chunk); j++) {
  353.                                 strcat(chunk, "0");
  354.                         }
  355.                 }
  356.    
  357.                 out = map_hex_to_rigol(chunk);
  358.    
  359.                 if (out) {
  360.                         strcat(temp, out);
  361.                 }
  362.    
  363.                 i = i + 5;
  364.         }
  365.        
  366.         strcpy(lic2_key, temp);
  367.  
  368.         strcpy(temp, lic1_key);
  369.         strcat(temp, lic2_key);
  370.  
  371.         /* now add the options */
  372.         memcpy(final,      temp     , 1);
  373.         final[1] = options[0];
  374.         memcpy(final +  2, temp +  1, 7);
  375.         final[9] = options[1];
  376.         memcpy(final + 10, temp +  8, 7);
  377.         final[17] = options[2];
  378.         memcpy(final + 18, temp + 15, 7);
  379.         final[25] = options[3];
  380.         memcpy(final + 26, temp + 22, 4);
  381.        
  382.         printf("----------------------------------------------------\n");
  383.         printf("your-license-key: ");
  384.        
  385.         for(i = 0; i < strlen(final); i++) {
  386.                 if (i % 7 == 0 && i > 0) printf("-");
  387.                 printf("%c", final[i]);
  388.         }
  389.  
  390.         printf("\n");
  391.         printf("----------------------------------------------------\n");
  392. }
RAW Paste Data
Top