summaryrefslogtreecommitdiffstats
path: root/utils/ypr0tools
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ypr0tools')
-rw-r--r--utils/ypr0tools/Makefile23
-rwxr-xr-xutils/ypr0tools/MuonEncryptbin11006 -> 0 bytes
-rw-r--r--utils/ypr0tools/README6
-rw-r--r--utils/ypr0tools/common.c94
-rw-r--r--utils/ypr0tools/common.h86
-rw-r--r--utils/ypr0tools/extract_section.c85
-rw-r--r--utils/ypr0tools/fwcrypt.c170
-rw-r--r--utils/ypr0tools/fwdecrypt.c168
-rwxr-xr-xutils/ypr0tools/pack-firmware.sh132
-rwxr-xr-xutils/ypr0tools/test.sh85
-rwxr-xr-xutils/ypr0tools/unpack-firmware.sh90
11 files changed, 621 insertions, 318 deletions
diff --git a/utils/ypr0tools/Makefile b/utils/ypr0tools/Makefile
index efc1de63f2..3efdc61443 100644
--- a/utils/ypr0tools/Makefile
+++ b/utils/ypr0tools/Makefile
@@ -1,13 +1,20 @@
+DEFINES=
+CC=gcc
+LD=gcc
+CFLAGS=-g -std=c99 -W -Wall $(DEFINES)
+LDFLAGS=
+BINS=fwcrypt fwdecrypt
-.PHONY: all clean
-PROGS = extract_section
-CC = gcc
-CFLAGS = -O1 -g -W -Wall
+all: $(BINS)
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
-all: $(PROGS)
- $(MAKE) -C cramfs-1.1
+fwdecrypt: fwdecrypt.o common.o ../../tools/fwpatcher/md5.o
+ $(LD) -o $@ $^ $(LDFLAGS)
+
+fwcrypt: fwcrypt.o common.o ../../tools/fwpatcher/md5.o
+ $(LD) -o $@ $^ $(LDFLAGS)
clean:
- $(MAKE) -C cramfs-1.1 clean
- rm -f extract_section
+ rm -fr *.o $(BINS)
diff --git a/utils/ypr0tools/MuonEncrypt b/utils/ypr0tools/MuonEncrypt
deleted file mode 100755
index b1bc124523..0000000000
--- a/utils/ypr0tools/MuonEncrypt
+++ /dev/null
Binary files differ
diff --git a/utils/ypr0tools/README b/utils/ypr0tools/README
index c517eec037..7d741bfcd3 100644
--- a/utils/ypr0tools/README
+++ b/utils/ypr0tools/README
@@ -2,9 +2,9 @@
To generate a firmware, run (paths may differ):
$ make
-$ ./unpack-firmware.sh R0.ROM /tmp/romfiles
-$ sudo ./patch-firmware.sh files /tmp/romfiles # needs sudo
-$ ./pack-firmware.sh R0.ROM /tmp/romfiles
+$ ./fwdecrypt R0.ROM <optional: destination path>
+$ sudo ./patch-firmware.sh files . # needs sudo
+$ ./fwcrypt R0.ROM <optional: source path>
After that, R0.ROM is patched and can load Rockbox.
diff --git a/utils/ypr0tools/common.c b/utils/ypr0tools/common.c
new file mode 100644
index 0000000000..fd42602d58
--- /dev/null
+++ b/utils/ypr0tools/common.c
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <stdint.h>
+#include "common.h"
+#include "../../tools/fwpatcher/md5.h"
+
+uint8_t g_yp_key[] =
+{
+ 0xa3, 0x04, 0xb9, 0xcd, 0x34, 0x13, 0x4a, 0x19, 0x19, 0x31, 0xdf, 0xbb,
+ 0x8f, 0x3d, 0x7f, 0x09, 0x42, 0x3c, 0x96, 0x33, 0x41, 0xa9, 0x95, 0xf1,
+ 0xd0, 0xac, 0x16, 0x37, 0x57, 0x35, 0x28, 0xe7, 0x0b, 0xc2, 0x12, 0x09,
+ 0x39, 0x42, 0xd2, 0x96, 0xf5, 0x00, 0xd2, 0x23, 0x37, 0x24, 0xe2, 0x8e,
+ 0x50, 0x3c, 0x6e, 0x23, 0xeb, 0x68, 0xed, 0x31, 0xb7, 0xee, 0xc0, 0xc7,
+ 0x09, 0xf8, 0x39, 0x9d, 0x51, 0xed, 0x17, 0x95, 0x64, 0x09, 0xe0, 0xf9,
+ 0xf0, 0xef, 0x86, 0xc0, 0x04, 0x46, 0x89, 0x8a, 0x6e, 0x27, 0x69, 0xde,
+ 0xc7, 0x31, 0x1e, 0xee, 0x3c, 0x3f, 0x17, 0x05, 0x44, 0xbb, 0xbb, 0x1d,
+ 0x3d, 0x5d, 0x6e, 0xf2, 0x78, 0x15, 0xd6, 0x3c, 0xcc, 0x7d, 0x67, 0x1a,
+ 0xb8, 0xd2, 0x79, 0x54, 0x97, 0xa2, 0x58, 0x58, 0xf7, 0x4e, 0x5e, 0x50,
+ 0x42, 0x69, 0xdc, 0xe7, 0x3a, 0x87, 0x2e, 0x22
+};
+
+char* firmware_components[] = {"MBoot", "Linux", "RootFS", "Sysdata"};
+char* firmware_filenames[] = {"MBoot.bin", "zImage", "cramfs-fsl.rom", "SYSDATA.bin"};
+
+void cyclic_xor(void *data, int datasize, void *xor, int xorsize)
+{
+ for(int i = 0; i < datasize; i++)
+ *(uint8_t *)(data + i) ^= *(uint8_t *)(xor + (i % xorsize));
+}
+
+size_t get_filesize(FILE* handle)
+{
+ long size = 0;
+ long old_pos = ftell(handle);
+ fseek(handle, 0, SEEK_END);
+ size = ftell(handle);
+ fseek(handle, old_pos, SEEK_SET);
+ return size;
+}
+
+/* A very rough implementation... */
+void join_path(char* destination, char* first, char* second)
+{
+ memset(destination, 0, MAX_PATH);
+ if (first != NULL && strlen(first) > 0)
+ {
+ strcpy(destination, first);
+ if (destination[strlen(destination) - 1] != DIR_SEPARATOR)
+ {
+ int l = strlen(destination);
+ destination[l] = DIR_SEPARATOR;
+ destination[l + 1] = '\0';
+ }
+ }
+ strcat(destination, second);
+}
+
+void md5sum(char* md5sum_string, char* data, unsigned long size)
+{
+ uint8_t md5_checksum[16];
+ md5_context c;
+ md5_starts(&c);
+ md5_update(&c, (unsigned char*)data, size);
+ md5_finish(&c, md5_checksum);
+ memset(md5sum_string, 0, MD5_DIGEST_LENGTH*2+1);
+ for (int i = 0; i < MD5_DIGEST_LENGTH; i++)
+ {
+ sprintf(md5sum_string, "%02x", md5_checksum[i]);
+ md5sum_string+=2;
+ }
+}
diff --git a/utils/ypr0tools/common.h b/utils/ypr0tools/common.h
new file mode 100644
index 0000000000..16aa3acf53
--- /dev/null
+++ b/utils/ypr0tools/common.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <stdint.h>
+
+#if defined(WIN32)
+# define DIR_SEPARATOR '\\'
+#else
+# define DIR_SEPARATOR '/'
+#endif
+
+#define MAX_PATH 255
+
+/*
+ * Firmware description
+ */
+
+#define GENERIC_HEADER_LINES 5
+#define MAX_HEADER_LEN 1000
+/* Empty space used by bootloader to store checksums */
+#define MBOOT_CHECKSUM_OFFSET 96
+/* Length of the reserved space */
+#define MBOOT_CHECKSUM_LENGTH 992
+
+/* In case we don't have RevisionInfo.txt file, mock values are fine */
+#define YPR0_VERSION "Version : V1.25\n"
+#define YPR0_TARGET "Target : KR\n"
+#define YPR0_USER "User : rockbox\n"
+#define YPR0_DIR "Dir : /.rockbox\n"
+#define YPR0_TIME "BuildTime : 11/04/20 14:17:34\n"
+
+#define YPR0_COMPONENTS_COUNT 4
+
+#define MD5_DIGEST_LENGTH 16
+
+extern char* firmware_components[];
+extern char* firmware_filenames[];
+extern uint8_t g_yp_key[128];
+
+struct firmware_data
+{
+ char* component_data[YPR0_COMPONENTS_COUNT];
+ size_t component_size[YPR0_COMPONENTS_COUNT];
+ char component_checksum[YPR0_COMPONENTS_COUNT][MD5_DIGEST_LENGTH*2+1];
+};
+
+enum samsung_error_t
+{
+ SAMSUNG_SUCCESS = 0,
+ SAMSUNG_READ_ERROR = -1,
+ SAMSUNG_FORMAT_ERROR = -2,
+ SAMSUNG_MD5_ERROR = -3,
+ SAMSUNG_WRITE_ERROR = -4,
+};
+
+void cyclic_xor(void *data, int datasize, void *xor, int xorsize);
+size_t get_filesize(FILE* handle);
+void join_path(char* destination, char* first, char* second);
+void md5sum(char* component_checksum, char* data, unsigned long size);
+
+#endif /* _COMMON_H_ */
diff --git a/utils/ypr0tools/extract_section.c b/utils/ypr0tools/extract_section.c
deleted file mode 100644
index 8ad12bc7df..0000000000
--- a/utils/ypr0tools/extract_section.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2011 Thomas Martitz
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-/* A simple replacement program for (
- * dd if=$file1 of=$file2 bs=1 skip=$offset count=$size
- *
- * Written because byte-size operations with dd are unbearably slow.
- */
-
-void usage(void)
-{
- fprintf(stderr, "Usage: extract_section <romfile> <outfile> <offset> <byte count>\n");
- exit(1);
-}
-
-void die(const char* fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
- exit(1);
-}
-
-int main(int argc, const char* argv[])
-{
- if (argc != 5)
- usage();
-
- int ifd, ofd;
- ssize_t size = atol(argv[4]);
- long skip = atol(argv[3]);
-
- if (!size)
- die("invalid byte count\n");
-
- ifd = open(argv[1], O_RDONLY);
- if (ifd < 0)
- die("Could not open %s for reading!\n", argv[1]);
-
- ofd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
- if (ofd < 0)
- die("Could not create %s\n", argv[2]);
-
- void *buf = malloc(size);
- if (!buf) die("OOM\n");
-
- lseek(ifd, skip, SEEK_SET);
- lseek(ofd, 0, SEEK_SET);
- if (read(ifd, buf, size) != size)
- die("Read failed\n");
- if (write(ofd, buf, size) != size)
- die("write failed\n");
-
- close(ifd);
- close(ofd);
-
- exit(EXIT_SUCCESS);
-}
diff --git a/utils/ypr0tools/fwcrypt.c b/utils/ypr0tools/fwcrypt.c
new file mode 100644
index 0000000000..e99d8872ba
--- /dev/null
+++ b/utils/ypr0tools/fwcrypt.c
@@ -0,0 +1,170 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <stdint.h>
+#include "common.h"
+
+static char* input_dir = NULL;
+static FILE* output_file = NULL;
+static struct firmware_data fw;
+
+static void cleanup(void)
+{
+ for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++)
+ {
+ free(fw.component_data[i]);
+ }
+}
+
+static void die(int error)
+{
+ if (output_file != NULL)
+ fclose(output_file);
+ free(input_dir);
+ cleanup();
+ exit(error);
+}
+
+int main(int argc, char **argv)
+{
+ FILE* component_handle = NULL;
+ FILE* rev_info_file = NULL;
+ int error = 0;
+ char* tmp_path = malloc(MAX_PATH);
+
+ memset(&fw, 0, sizeof(fw));
+
+ if (argc < 2)
+ {
+ printf(
+ "Crypts Samsung YP-R0/YP-R1 ROM file format\n"
+ "Usage: fwcrypt <output ROM file path\n"
+ );
+ return 1;
+ }
+
+ input_dir = malloc(MAX_PATH);
+ input_dir[0] = '\0';
+ if (argc > 2)
+ {
+ strcpy(input_dir, argv[2]);
+ }
+
+ /* open the output file for write */
+ output_file = fopen(argv[1], "wb");
+ if (output_file == NULL)
+ {
+ fprintf(stderr, "Cannot open file for writing: %m\n");
+ die(SAMSUNG_WRITE_ERROR);
+ }
+
+ /* write generic header */
+ join_path(tmp_path, input_dir, "RevisionInfo.txt");
+ rev_info_file = fopen(tmp_path, "rb");
+ if (rev_info_file != NULL)
+ {
+ for (int i = 0; i < GENERIC_HEADER_LINES; i++)
+ {
+ char header[MAX_HEADER_LEN];
+ error += fgets(header, MAX_HEADER_LEN, rev_info_file) == NULL;
+ error += fprintf(output_file, "%s", header) != (signed)strlen(header);
+ }
+ fclose(rev_info_file);
+ }
+ else
+ {
+ /* write some generic information */
+ error += fprintf(output_file, YPR0_VERSION) != strlen(YPR0_VERSION);
+ error += fprintf(output_file, YPR0_TARGET) != strlen(YPR0_TARGET);
+ error += fprintf(output_file, YPR0_USER) != strlen(YPR0_USER);
+ error += fprintf(output_file, YPR0_DIR) != strlen(YPR0_DIR);
+ error += fprintf(output_file, YPR0_TIME) != strlen(YPR0_TIME);
+ }
+
+ if(error != 0)
+ {
+ fprintf(stderr, "Cannot write generic header\n");
+ die(SAMSUNG_WRITE_ERROR);
+ }
+
+ for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++)
+ {
+ join_path(tmp_path, input_dir, firmware_filenames[i]);
+ component_handle = fopen(tmp_path, "rb");
+ if (component_handle == NULL)
+ {
+ fprintf(stderr, "Error while reading firmware component.\n");
+ die(SAMSUNG_READ_ERROR);
+ }
+ fw.component_size[i] = get_filesize(component_handle);
+ fw.component_data[i] = malloc(fw.component_size[i] * sizeof(char));
+ fread(fw.component_data[i], sizeof(char), fw.component_size[i], component_handle);
+ fclose(component_handle);
+
+ /* compute checksum */
+ md5sum(fw.component_checksum[i], fw.component_data[i], fw.component_size[i]);
+ printf("%s : size(%ld),checksum(%s)\n", firmware_components[i],
+ fw.component_size[i], fw.component_checksum[i]);
+ /* write metadata header to file */
+ if (fprintf(output_file, "%s : size(%ld),checksum(%s)\n", firmware_components[i],
+ fw.component_size[i], fw.component_checksum[i]) < 0)
+ {
+ fprintf(stderr, "Error writing to output file.\n");
+ die(SAMSUNG_WRITE_ERROR);
+ }
+ }
+
+ /* write final data to the firmware file */
+ for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++)
+ {
+ /* the bootloader needs to be patched: add checksum of the components */
+ if (strcmp("MBoot", firmware_components[i]) == 0)
+ {
+ int index=MBOOT_CHECKSUM_OFFSET;
+ for (int z = 0; z < YPR0_COMPONENTS_COUNT; z++)
+ {
+ index += sprintf(fw.component_data[i] + index, "%ld:%s\n",
+ fw.component_size[z], fw.component_checksum[z]);
+ }
+ }
+ /* crypt data */
+ cyclic_xor(fw.component_data[i], fw.component_size[i], g_yp_key, sizeof(g_yp_key));
+ /* write data */
+ size_t written = fwrite(fw.component_data[i], sizeof(char),
+ fw.component_size[i], output_file);
+ if (written != fw.component_size[i])
+ {
+ fprintf(stderr, "%s: error writing data to file. Written %ld bytes\n",
+ firmware_components[i], written);
+ die(SAMSUNG_WRITE_ERROR);
+ }
+ /* padding */
+ if (i < (YPR0_COMPONENTS_COUNT-1))
+ fputs("\0\0\0\0", output_file);
+ }
+
+ /* free the big amount of memory and close handles */
+ die(SAMSUNG_SUCCESS);
+}
diff --git a/utils/ypr0tools/fwdecrypt.c b/utils/ypr0tools/fwdecrypt.c
new file mode 100644
index 0000000000..eb611feb37
--- /dev/null
+++ b/utils/ypr0tools/fwdecrypt.c
@@ -0,0 +1,168 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "common.h"
+
+static char* output_dir = NULL;
+static FILE* input_file = NULL;
+static struct firmware_data fw;
+
+static void cleanup(void)
+{
+ for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++)
+ {
+ free(fw.component_data[i]);
+ }
+}
+
+static void die(int error)
+{
+ if (input_file != NULL)
+ fclose(input_file);
+ free(output_dir);
+ cleanup();
+ exit(error);
+}
+
+int main(int argc, char **argv)
+{
+ FILE* component_handle = NULL;
+ FILE* rev_info_file = NULL;
+ char* tmp_path = malloc(MAX_PATH);
+ int error = 0;
+ bool md5sum_error = false;
+
+ memset(&fw, 0, sizeof(fw));
+
+ if (argc < 2)
+ {
+ printf("Decrypts Samsung YP-R0/YP-R1 ROM file format\n"
+ "Usage: fwdecrypt <ROM file path\n"
+ );
+ return 1;
+ }
+
+ output_dir = malloc(MAX_PATH);
+ output_dir[0] = '\0';
+ if (argc > 2)
+ {
+ strcpy(output_dir, argv[2]);
+ }
+
+ /* open the output file for write */
+ input_file = fopen(argv[1], "rb");
+ if (input_file == NULL)
+ {
+ fprintf(stderr, "Cannot open file for reading: %m\n");
+ die(SAMSUNG_READ_ERROR);
+ }
+
+ /* read some generic information */
+ join_path(tmp_path, output_dir, "RevisionInfo.txt");
+ rev_info_file = fopen(tmp_path, "w");
+ for (int i = 0; i < 5; i++)
+ {
+ char info[MAX_HEADER_LEN];
+ error += fgets(info, MAX_HEADER_LEN, input_file) == NULL;
+ printf("%s", info);
+ if (rev_info_file != NULL)
+ fprintf(rev_info_file, "%s", info);
+ }
+ if (rev_info_file != NULL)
+ fclose(rev_info_file);
+
+ if (error != 0)
+ {
+ fprintf(stderr, "Cannot write generic header\n");
+ die(SAMSUNG_WRITE_ERROR);
+ }
+
+ /* read metadata */
+ for (int i = 0; i < YPR0_COMPONENTS_COUNT; i++)
+ {
+ char metadata[MAX_HEADER_LEN];
+ error += fgets(metadata, MAX_HEADER_LEN, input_file) == NULL;
+ error += sscanf(metadata, "%*s : size(%ld),checksum(%s)",
+ &fw.component_size[i], fw.component_checksum[i]) != 2;
+ /* strip last ")" */
+ fw.component_checksum[i][strlen(fw.component_checksum[i])-1] = '\0';
+ printf("%s: %ld bytes -- MD5 %s\n", firmware_components[i],
+ fw.component_size[i], fw.component_checksum[i]);
+ }
+
+ /* We start from the end because ROM header could have a different
+ * line count or extra new-lines (noticed in some hacked ROMs)
+ */
+ size_t current_pos = get_filesize(input_file);
+ for (int i = YPR0_COMPONENTS_COUNT-1; i >= 0; i--)
+ {
+
+ fw.component_data[i] = malloc(fw.component_size[i]);
+ current_pos -= fw.component_size[i];
+ fseek(input_file, current_pos, SEEK_SET);
+ size_t bread = fread(fw.component_data[i], 1, fw.component_size[i], input_file);
+ if (bread != fw.component_size[i])
+ fprintf(stderr, "%s: Read size mismatch: read %ld bytes, expected %ld bytes\n",
+ firmware_components[i], bread, fw.component_size[i]);
+
+ /* decrypt data */
+ cyclic_xor(fw.component_data[i], fw.component_size[i], g_yp_key, sizeof(g_yp_key));
+
+ /* unpatch bootloader */
+ if (strcmp("MBoot", firmware_components[i]) == 0)
+ {
+ memset(fw.component_data[i] + MBOOT_CHECKSUM_OFFSET, 0, MBOOT_CHECKSUM_LENGTH);
+ }
+
+ char md5sum_decrypted[MD5_DIGEST_LENGTH*2+1];
+
+ md5sum(md5sum_decrypted, fw.component_data[i], fw.component_size[i]);
+
+ if (strcmp(md5sum_decrypted, fw.component_checksum[i]) != 0)
+ {
+ printf("%s: FAIL (md5sum doesn't match)\n", firmware_components[i]);
+ md5sum_error = true;
+ }
+
+ join_path(tmp_path, output_dir, firmware_filenames[i]);
+ component_handle = fopen(tmp_path, "wb");
+
+ if (component_handle == NULL)
+ {
+ fprintf(stderr, "Error opening file for writing. Is the directory valid and writeable?\n");
+ die(SAMSUNG_WRITE_ERROR);
+ }
+
+ fwrite(fw.component_data[i], 1, fw.component_size[i], component_handle);
+ fclose(component_handle);
+
+ }
+
+ if (md5sum_error)
+ die(SAMSUNG_MD5_ERROR);
+ die(SAMSUNG_SUCCESS);
+}
diff --git a/utils/ypr0tools/pack-firmware.sh b/utils/ypr0tools/pack-firmware.sh
deleted file mode 100755
index f3b55548d9..0000000000
--- a/utils/ypr0tools/pack-firmware.sh
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/bin/bash
-
-######################################################################
-# __________ __ ___.
-# Open \______ \ ____ ____ | | _\_ |__ _______ ___
-# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
-# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
-# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
-# \/ \/ \/ \/ \/
-#
-# * Script to generate a Samsung YP-R0 firmware file (R0.ROM) */
-######################################################################
-#
-# This file was oringally called NewPack.sh, its origin is the R0 open source
-# package from Samsung.
-#
-# Muon Platform
-# Copyright (c) 2004-2009 Samsung Electronics, Inc.
-# All rights reserved.
-#
-# Rom Packaging Script
-# It needs sudoer privilege of rm, mkdir, cp, mkcramfs.
-# You can configure it in the /etc/sudoer file.
-# This script is very dangerous. Be careful to use.
-#
-# SangMan Sim<sangman.sim@samsung.com>
-
-# bail out early
-set -e
-
-DIR=${2:-"."}
-DIR=${DIR%/}
-REVISION="$DIR/RevisionInfo.txt"
-CRAMFS="$DIR/cramfs-fsl.rom"
-SYSDATA="$DIR/SYSDATA.bin"
-MBOOT="$DIR/MBoot.bin"
-MBOOT_TMP="${TMP_DIR:-$DIR}/MBoot.tmp"
-LINUX="$DIR/zImage"
-R0ROM=$1
-
-# some sanity checks
-if [ $# -lt 1 ] || [ $# -gt 2 ]; then
- echo "Usage $0 <rom file> [path to image files]"
- exit 1
-fi
-
-if [ ! -f ./MuonEncrypt ]; then
- echo "Couldn't find MuonEncrypt binary (try 'make')"
- exit 1
-fi
-
-if [ ! -e $REVISION ]; then
- cat >$REVISION <<EOF
-Version : V2.30
-Target : KR
-EOF
-fi
-
-
-function WriteImage {
- echo "Adding $1 to $R0ROM"
- #HEAD_STR=[`stat -c%s $1`/`md5sum $1 | cut -d " " -f 1`]
- #HEAD_SIZE=`echo $HEAD_STR | wc -c`
- #PACK_SIZE=`expr 44 - $HEAD_SIZE`
-
- #while [ $PACK_SIZE -gt 0 ]
- #do
- #PACK_SIZE=`expr $PACK_SIZE - 1`
- #echo -n 0
- #done
-
- ./MuonEncrypt $1 >> $R0ROM
- #cat $MBOOT >> $R0ROM
-}
-
-function Pack4Byte {
- FILE_SIZE=`stat -c%s $R0ROM`
- PACK_SIZE=`expr 4 - $FILE_SIZE % 4`
-
- if [ $PACK_SIZE != 4 ]
- then
- while [ $PACK_SIZE -gt 0 ]
- do
- PACK_SIZE=`expr $PACK_SIZE - 1` || true
- echo -en $1 >> $R0ROM
- done
- fi
-
-}
-
-echo Make $R0ROM
-
-cat $REVISION > $R0ROM
-echo User : $USER >> $R0ROM
-echo Dir : $PWD >> $R0ROM
-echo BuildTime : `date "+%y/%m/%d %H:%M:%S"` >> $R0ROM
-echo MBoot : size\(`stat -c%s $MBOOT`\),checksum\(`md5sum $MBOOT | cut -d " " -f 1`\) >> $R0ROM
-echo Linux : size\(`stat -c%s $LINUX`\),checksum\(`md5sum $LINUX | cut -d " " -f 1`\) >> $R0ROM
-echo RootFS : size\(`stat -c%s $CRAMFS`\),checksum\(`md5sum $CRAMFS | cut -d " " -f 1`\) >> $R0ROM
-echo Sysdata : size\(`stat -c%s $SYSDATA`\),checksum\(`md5sum $SYSDATA | cut -d " " -f 1`\) >> $R0ROM
-
-Pack4Byte "\\n"
-
-
-dd if=$MBOOT of=$MBOOT_TMP bs=96 count=1 2> /dev/null
-
-echo `stat -c%s $MBOOT`:`md5sum $MBOOT | cut -d " " -f 1` >> $MBOOT_TMP
-echo `stat -c%s $LINUX`:`md5sum $LINUX | cut -d " " -f 1` >> $MBOOT_TMP
-echo `stat -c%s $CRAMFS`:`md5sum $CRAMFS | cut -d " " -f 1` >> $MBOOT_TMP
-echo `stat -c%s $SYSDATA`:`md5sum $SYSDATA | cut -d " " -f 1` >> $MBOOT_TMP
-
-dd if=$MBOOT of=$MBOOT_TMP bs=1088 skip=1 seek=1 2> /dev/null
-WriteImage $MBOOT_TMP
-
-#rm $MBOOT_TMP
-
-Pack4Byte "0"
-
-WriteImage $LINUX
-
-Pack4Byte "0"
-
-WriteImage $CRAMFS
-
-Pack4Byte "0"
-
-WriteImage $SYSDATA
-
-echo $R0ROM : `stat -c%s $R0ROM`, `md5sum $R0ROM | cut -d " " -f 1`
-#head -9 $R0ROM
-
-echo "Done"
diff --git a/utils/ypr0tools/test.sh b/utils/ypr0tools/test.sh
new file mode 100755
index 0000000000..3c891e6e7f
--- /dev/null
+++ b/utils/ypr0tools/test.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+######################################################################
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+#
+# Script to test packer and unpacker
+# Copyright (C) 2013 Lorenzo Miori
+######################################################################
+
+ROM_FILE="$1"
+TMP_FOLDER=""
+
+goto_temp()
+{
+ if [ -n "$TMP_FOLDER" ]
+ then
+ cd $TMP_FOLDER
+ fi
+}
+
+cleanup()
+{
+ echo "$1"
+ OLD_DIR=`pwd`
+ goto_temp
+ rm -f "$ROM_FILE"_TEST_CRYPT "MBoot.bin" "zImage" "cramfs-fsl.rom" "SYSDATA.bin" "TEST_MD5SUMS" "RevisionInfo.txt" > /dev/null
+ cd $OLD_DIR
+ if [ -n "$TMP_FOLDER" ]
+ then
+ rmdir $TMP_FOLDER
+ fi
+ make clean
+ exit $2
+}
+
+if [ $# -lt 1 ]
+then
+ cleanup "FAIL: Missing parameter! Run with: test.sh <path to working rom to test> <optional: destination to temporary files>" 1
+fi
+
+if [ $# -eq 2 ]
+then
+ TMP_FOLDER="$2/"
+ mkdir $TMP_FOLDER
+ if [ $? -ne 0 ]
+ then
+ echo "FAIL: temporary directory exists!"
+ fi
+fi
+
+# be sure we have the executables up-to-date
+make clean
+make
+
+./fwdecrypt $1 $TMP_FOLDER
+if [ $? -ne 0 ]
+then
+ cleanup "FAIL: Error while decrypting ROM file" 1
+fi
+
+./fwcrypt $TMP_FOLDER$1_TEST_CRYPT $TMP_FOLDER
+if [ $? -ne 0 ]
+then
+ cleanup "FAIL: Error while decrypting ROM file" 1
+fi
+
+OLD_DIR=`pwd`
+goto_temp
+
+md5sum MBoot.bin zImage cramfs-fsl.rom SYSDATA.bin RevisionInfo.txt > "TEST_MD5SUMS"
+
+md5sum --strict -c "TEST_MD5SUMS"
+if [ $? -ne 0 ]
+then
+ cleanup "FAIL: MD5SUM mismatch!" 1
+fi
+
+cd $OLD_DIR
+
+cleanup "OK: test completed without errors." 0
diff --git a/utils/ypr0tools/unpack-firmware.sh b/utils/ypr0tools/unpack-firmware.sh
deleted file mode 100755
index ab80670c79..0000000000
--- a/utils/ypr0tools/unpack-firmware.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/bash
-
-######################################################################
-# __________ __ ___.
-# Open \______ \ ____ ____ | | _\_ |__ _______ ___
-# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
-# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
-# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
-# \/ \/ \/ \/ \/
-#
-# * Script to unpack a Samsung YP-R0 firmware file (R0.ROM) */
-######################################################################
-
-# The file was originally called MuonDecrypt.sh
-#
-# I'm not sure about the original author of this file, as it wasn't included in Samsung package.
-# But I guess it was done by JeanLouis, an Italian user of the Hardware Upgrade Forum. If needed, we should search throug old posts for that...
-#
-
-
-# bail out early
-set -e
-
-# some sanity checks
-if [ $# -lt 1 ] || [ $# -gt 2 ]; then
- echo "Usage $0 <rom file> [out dir]"
- exit 1
-fi
-
-
-ROM=$1
-DIR=${2:-"."}
-DIR=${DIR%/}
-MBOOT="$DIR/MBoot.bin"
-MBOOT_TMP="${TMP_DIR:-$DIR}/MBoot.tmp"
-LINUX="$DIR/zImage"
-CRAMFS="$DIR/cramfs-fsl.rom"
-SYSDATA="$DIR/SYSDATA.bin"
-MD5SUMS="$DIR/MD5SUMS"
-TMP="${TMP_DIR:-$DIR}/_$$.tmp"
-
-
-if [ ! -f ./extract_section ]; then
- echo "Couldn't find extract_section binary (try 'make')"
- exit 1
-fi
-
-if [ ! -f ./MuonEncrypt ]; then
- echo "Couldn't find MuonEncrypt binary (try 'make')"
- exit 1
-fi
-
-mkdir -p $DIR
-
-if [ ! -w $DIR ]; then
- echo "Target dir not writable"
- exit 1
-fi
-
-ExtractAndDecrypt() {
- START=$(expr $START - $2)
- echo "Extracting $1..."
- ./extract_section $ROM $TMP $START $2
- echo "Decrypt $1..."
- ./MuonEncrypt $TMP > $1
-}
-
-size=( `head -n 9 $ROM | tail -n 4 | while read LINE; do echo $LINE | cut -d\( -f 2 | cut -d\) -f 1; done`)
-checksum=( `head -n 9 $ROM | tail -n 4 | while read LINE; do echo $LINE | cut -d\( -f 3 | cut -d\) -f 1; done`)
-
-echo "${checksum[0]} $MBOOT" > $MD5SUMS
-echo "${checksum[1]} $LINUX" >> $MD5SUMS
-echo "${checksum[2]} $CRAMFS" >> $MD5SUMS
-echo "${checksum[3]} $SYSDATA" >> $MD5SUMS
-
-START=`stat -c%s $ROM`
-
-ExtractAndDecrypt $SYSDATA ${size[3]}
-ExtractAndDecrypt $CRAMFS ${size[2]}
-ExtractAndDecrypt $LINUX ${size[1]}
-ExtractAndDecrypt $MBOOT_TMP ${size[0]}
-
-rm $TMP
-echo "Create $MBOOT..."
-dd if=$MBOOT_TMP of=$MBOOT bs=96 count=1 2>/dev/null
-dd if=$MBOOT_TMP of=$MBOOT bs=1088 skip=1 seek=1 2>/dev/null
-rm $MBOOT_TMP
-
-echo "Check integrity:"
-md5sum -c $MD5SUMS