Guest User

rigolkey.c

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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×