/tools/mk500boot.c

https://gitlab.com/GrieverV/rockbox · C · 322 lines · 206 code · 58 blank · 58 comment · 43 complexity · 8b42d8442b3eb61760c9eba290638511 MD5 · raw file

  1. /***************************************************************************
  2. * __________ __ ___.
  3. * Open \______ \ ____ ____ | | _\_ |__ _______ ___
  4. * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
  5. * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
  6. * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
  7. * \/ \/ \/ \/ \/
  8. *
  9. * Copyright (C) 2009 by Karl Kurbjun
  10. * $Id$
  11. *
  12. * All files in this archive are subject to the GNU General Public License.
  13. * See the file COPYING in the source tree root for full license agreement.
  14. *
  15. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  16. * KIND, either express or implied.
  17. *
  18. ****************************************************************************/
  19. #include <stdio.h>
  20. #include <errno.h>
  21. #include <inttypes.h>
  22. #include <string.h>
  23. #include "mr500.h"
  24. /* This is the patch necessary for the SVG exploit (decrypted) */
  25. struct patch_single hack[] = { {0x29B28, 0xE12FFF30},
  26. {0x2F960, 0xE12FFF30} };
  27. static void usage(void)
  28. {
  29. printf( "Usage: mk500boot <options> <input file> [output file]\n"
  30. "options:\n"
  31. "\t-decrypt Decrypt the input file and save the output file\n"
  32. "\t-encrypt Encrypt the input file and save the output file\n"
  33. "\t-patch Patch the input file with the SVF hack\n\n");
  34. exit(1);
  35. }
  36. /* This is a fake flag that is used to let the tool know what's up */
  37. #define HEADER_DECRYPTED 0x8000
  38. void display_header(struct olympus_header *header) {
  39. printf("Magic Name: \t%s\n", header->magic_name);
  40. printf("Unknown: \t0x%08hX\n", header->unknown);
  41. printf("Header Length: \t0x%04X\n", header->header_length);
  42. printf("Flags: \t\t0x%04X\n", header->flags);
  43. printf("Unknonwn Zeros: 0x%08X\n", header->unknown_zeros);
  44. printf("Image Length: \t0x%08X\n", header->image_length);
  45. }
  46. /* This is a demonstration of the encryption and decryption process.
  47. * It patches a FW image to include the SVG exploit.
  48. */
  49. int main (int argc, char *argv[]) {
  50. uint32_t checksum;
  51. uint32_t stored_crc;
  52. enum operations {
  53. decrypt,
  54. encrypt,
  55. patch
  56. } operation;
  57. char *encrypt_file;
  58. char *decrypt_file;
  59. struct olympus_header header;
  60. if (argc < 2) {
  61. usage();
  62. return -1;
  63. }
  64. if(!strcmp(argv[1], "-decrypt")) {
  65. if(argc < 3) {
  66. usage();
  67. return -1;
  68. }
  69. encrypt_file=argv[2];
  70. decrypt_file=argv[3];
  71. operation = decrypt;
  72. } else if(!strcmp(argv[1], "-encrypt")) {
  73. if(argc < 3) {
  74. usage();
  75. return -1;
  76. }
  77. decrypt_file = argv[2];
  78. encrypt_file = argv[3];
  79. operation = encrypt;
  80. } else if(!strcmp(argv[1], "-patch")) {
  81. decrypt_file = argv[2];
  82. encrypt_file = argv[3];
  83. operation = patch;
  84. } else {
  85. return -1;
  86. }
  87. /* Initialize encryption/decryption routine */
  88. mr500_init();
  89. if(operation == decrypt) {
  90. /* Read in the header of the encrypted file */
  91. if(mr500_read_header(encrypt_file, &header) < 0 ) {
  92. printf("ERROR: Unable to read header: %s\n", strerror(errno));
  93. return -1;
  94. }
  95. /* Read CRC of encrypted file */
  96. if(mr500_read_crc(encrypt_file,
  97. header.header_length+header.image_length, &stored_crc) < 0 ) {
  98. printf("ERROR: Unable to read CRC: %s\n", strerror(errno));
  99. return -1;
  100. }
  101. /* Display the header information */
  102. printf("File format:\n");
  103. printf("*****Header*****\n");
  104. display_header(&header);
  105. printf("****************\n\n");
  106. printf("*****Image******\n\n");
  107. printf("*****Footer*****\n");
  108. printf("Checksum: \t0x%08X\n", stored_crc);
  109. printf("****************\n\n");
  110. printf("Writing Decrypted file...\n");
  111. /*********************************************************************
  112. * Save a decrypted file
  113. **********************************************************************/
  114. /* Check to make sure this is a encrypted file (bogus flag not set) */
  115. if(header.flags & HEADER_DECRYPTED) {
  116. printf("ERROR: This appears to be a decrypted file! Quitting\n");
  117. return -1;
  118. }
  119. /* Check to make sure MAGIC string matches expected*/
  120. if(strncmp((char *)header.magic_name, "OIMCFWUP", 8)) {
  121. printf("ERROR: Magic string does not match expected! Quitting\n");
  122. return -1;
  123. }
  124. /* Set a bogus flag to let the tool know that this is a decrypted file*/
  125. header.flags |= HEADER_DECRYPTED;
  126. /* Start by writing out the header */
  127. if(mr500_save_header(decrypt_file, &header) < 0 ) {
  128. printf("ERROR: Unable to save header: %s\n", strerror(errno));
  129. return -1;
  130. }
  131. /* Read encrypted data and save decrypted data */
  132. if(mr500_save_data( encrypt_file, decrypt_file, header.header_length,
  133. header.image_length, decrypt_array) < 0 ) {
  134. printf("ERROR: Unable to save decrypted data: %s\n", strerror(errno));
  135. return -1;
  136. }
  137. printf("Calculating Checksum...\n");
  138. /* Calculate CRC of decrypted data */
  139. if(mr500_calculate_crc( decrypt_file, header.header_length,
  140. header.image_length, &checksum) < 0 ) {
  141. printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno));
  142. return -1;
  143. }
  144. printf("Calculated Checksum: \n\t\t0x%08X\n", checksum);
  145. /* Double check to make sure that the two CRCs match */
  146. if(checksum!=stored_crc) {
  147. printf("\tERROR: \tCalculated checksum: \t0x%08X and\n", checksum);
  148. printf("\t\tStored checksum: \t0x%08X do not match\n", stored_crc);
  149. return -1;
  150. } else {
  151. printf("\tOK: Calculated checksum and stored checksum match.\n");
  152. }
  153. printf("Saving Checksum...\n");
  154. /* Save the calculated CRC to the file */
  155. if(mr500_save_crc(decrypt_file, header.header_length+header.image_length,
  156. &checksum) < 0 ) {
  157. printf("ERROR: Unable to save CRC: %s\n", strerror(errno));
  158. return -1;
  159. }
  160. } else if(operation == patch) {
  161. /**********************************************************************
  162. * Patch decryped file with SVG exploit
  163. **********************************************************************/
  164. printf("Patching decrypted file.\n");
  165. /* Read in the header of the encrypted file */
  166. if(mr500_read_header(decrypt_file, &header) < 0 ) {
  167. printf("ERROR: Unable to read header: %s\n", strerror(errno));
  168. return -1;
  169. }
  170. /* Check to make sure this is a decrypted file (bogus flag not set) */
  171. if(!(header.flags & HEADER_DECRYPTED)) {
  172. printf("ERROR: This appears to be a encrypted file! Quitting\n");
  173. return -1;
  174. }
  175. /* Check to make sure MAGIC string matches expected*/
  176. if(strncmp((char *)header.magic_name, "OIMCFWUP", 8)) {
  177. printf("ERROR: Magic string does not match expected! Quitting\n");
  178. return -1;
  179. }
  180. printf("File Header:\n");
  181. display_header(&header);
  182. if(mr500_patch_file (decrypt_file, hack, 2) < 0 ) {
  183. printf("ERROR: Unable to patch file: %s\n", strerror(errno));
  184. return -1;
  185. }
  186. printf("\nCalculating new CRC\n");
  187. /* Calculate the 'CRC' of the patched file */
  188. if(mr500_calculate_crc( decrypt_file, header.header_length,
  189. header.image_length, &checksum) < 0 ) {
  190. printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno));
  191. return -1;
  192. }
  193. printf("Calculated CRC: \n\t\t0x%08X\n", checksum);
  194. /* Store the calculated 'CRC' (not encrypted) */
  195. if(mr500_save_crc(decrypt_file, header.header_length+header.image_length,
  196. &checksum) < 0 ) {
  197. printf("ERROR: Unable to save CRC: %s\n", strerror(errno));
  198. return -1;
  199. }
  200. } else if(operation == encrypt) {
  201. /**********************************************************************
  202. * Save an encrypted file
  203. **********************************************************************/
  204. printf("Saving Encrypted file\n");
  205. /* Read in the header of the encrypted file */
  206. if(mr500_read_header(decrypt_file, &header) < 0 ) {
  207. printf("ERROR: Unable to read header: %s\n", strerror(errno));
  208. return -1;
  209. }
  210. /* Check to make sure this is a decrypted file (bogus flag not set) */
  211. if(!(header.flags & HEADER_DECRYPTED)) {
  212. printf("ERROR: This appears to be a encrypted file! Quitting\n");
  213. return -1;
  214. }
  215. /* Check to make sure MAGIC string matches expected*/
  216. if(strncmp((char *)header.magic_name, "OIMCFWUP", 7)) {
  217. printf("ERROR: Magic string does not match expected! Quitting\n");
  218. return -1;
  219. }
  220. /* Remove the bogus flag */
  221. header.flags &= ~HEADER_DECRYPTED;
  222. printf("File Header:\n");
  223. display_header(&header);
  224. /* Header is not encrypted, save it */
  225. if(mr500_save_header(encrypt_file, &header) < 0 ) {
  226. printf("ERROR: Unable to save header: %s\n", strerror(errno));
  227. return -1;
  228. }
  229. /* Read CRC of decrypted file */
  230. if(mr500_read_crc(decrypt_file,
  231. header.header_length+header.image_length, &stored_crc) < 0 ) {
  232. printf("ERROR: Unable to read CRC: %s\n", strerror(errno));
  233. return -1;
  234. }
  235. /* Calculate the 'CRC' of the decrypted data */
  236. if(mr500_calculate_crc( decrypt_file, header.header_length,
  237. header.image_length, &checksum) < 0 ) {
  238. printf("ERROR: Unable to calculate CRC: %s\n", strerror(errno));
  239. return -1;
  240. }
  241. if(stored_crc != checksum) {
  242. printf("\nERROR: Stored and calculated checksums do not match!\n"
  243. "\tFile has been improperly modified. Quitting\n");
  244. return -1;
  245. }
  246. printf("Encrypting data...\n");
  247. /* Write the encrypted data to a file */
  248. if(mr500_save_data( decrypt_file, encrypt_file, header.header_length,
  249. header.image_length, encrypt_array) < 0 ) {
  250. printf("ERROR: Unable to save encrypted data: %s\n", strerror(errno));
  251. return -1;
  252. }
  253. printf("Saving CRC\n");
  254. /* Store the calculated 'CRC' (not encrypted) */
  255. if(mr500_save_crc(encrypt_file, header.header_length+header.image_length,
  256. &checksum) < 0 ) {
  257. printf("ERROR: Unable to save CRC: %s\n", strerror(errno));
  258. return -1;
  259. }
  260. printf("File sucesfully encrypted!\n");
  261. }
  262. printf("Done\n");
  263. return 0;
  264. }