Guest User

rigolkey.c

a guest
Jul 24th, 2013
6,143
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