FS#10740 - rbutil: Test Cowon D2 OF file for CRC consistency before patching

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23470 a1c6a512-1295-4272-9138-f99709370657
diff --git a/rbutil/mktccboot/mktccboot.c b/rbutil/mktccboot/mktccboot.c
index 432bc03..7103f23 100644
--- a/rbutil/mktccboot/mktccboot.c
+++ b/rbutil/mktccboot/mktccboot.c
@@ -175,6 +175,12 @@
     return NULL;
 }
 
+/* A CRC test in order to reject non OF file */
+int test_firmware_tcc(unsigned char* buf, int length)
+{
+    return telechips_test_crc(buf, length);
+}
+
 #ifndef LIB
 int main(int argc, char *argv[])
 {
@@ -185,7 +191,7 @@
     unsigned char *boot_buf = NULL;
     unsigned char* image = NULL;
     int ret = 0;
-    
+
     if(argc < 3) {
         usage();
     }
@@ -202,6 +208,14 @@
         goto error_exit;
     }
 
+    /* Validate input file */
+    if (test_firmware_tcc(of_buf, of_size))
+    {
+        printf("[ERR] Unknown OF file used, aborting\n");
+        ret = 2;
+        goto error_exit;
+    }
+
     boot_buf = file_read(bootfile, &boot_size);
     if (!boot_buf)
     {
diff --git a/rbutil/mktccboot/mktccboot.h b/rbutil/mktccboot/mktccboot.h
index 6c6410c..2df2c54 100644
--- a/rbutil/mktccboot/mktccboot.h
+++ b/rbutil/mktccboot/mktccboot.h
@@ -35,6 +35,9 @@
 
 unsigned char *file_read(char *filename, int *size);
 
+/* Test TCC firmware file for consistency using CRC test */
+int test_firmware_tcc(unsigned char* buf, int length);
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/rbutil/rbutilqt/base/bootloaderinstalltcc.cpp b/rbutil/rbutilqt/base/bootloaderinstalltcc.cpp
index 1d0a9e6..525421d 100644
--- a/rbutil/rbutilqt/base/bootloaderinstalltcc.cpp
+++ b/rbutil/rbutilqt/base/bootloaderinstalltcc.cpp
@@ -81,6 +81,14 @@
         goto exit;
     }
 
+    /* A CRC test in order to reject non OF file */
+    if (test_firmware_tcc(of_buf, of_size))
+    {
+        emit logItem(errstr, LOGERROR);
+        emit logItem(tr("Unknown OF file used: %1").arg(m_offile), LOGERROR);
+        goto exit;
+    }
+
     /* Load bootloader file */
     boot_buf = file_read(bootfile.toLocal8Bit().data(), &boot_size);
     if (boot_buf == NULL)
diff --git a/tools/telechips.c b/tools/telechips.c
index 8eefffc..acb15b8 100644
--- a/tools/telechips.c
+++ b/tools/telechips.c
@@ -31,6 +31,7 @@
 #include <fcntl.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 
 static uint32_t crctable[256];
 
@@ -57,11 +58,11 @@
 {
     int i;
     uint32_t r;
-    uint32_t index;
+    uint32_t idx;
 
-    for (index = 0; index < 256; index++)
+    for (idx = 0; idx < 256; idx++)
     {
-        r = bitreverse(index,8) << 24;
+        r = bitreverse(idx,8) << 24;
         for (i=0; i<8; i++)
         {
             if (r & (1 << 31))
@@ -69,7 +70,7 @@
             else
                 r<<=1;
         }
-        crctable[index] = bitreverse(r,32);
+        crctable[idx] = bitreverse(r,32);
     }
 }
 
@@ -156,3 +157,26 @@
         put_uint32le(buf+0x10, crc1);
     }
 }
+
+int telechips_test_crc(unsigned char* buf, int length)
+{
+    uint32_t crc1, crc2, test_crc1, test_crc2;
+    unsigned char *test_buf;
+
+    crc1 = get_uint32le(buf + 0x10);
+    crc2 = get_uint32le(buf + 0x18);
+
+    test_buf = malloc(length);
+    if (!test_buf)
+        return 1;
+
+    memcpy(test_buf, buf, length);
+    telechips_encode_crc(test_buf, length);
+
+    test_crc1 = get_uint32le(test_buf + 0x10);
+    test_crc2 = get_uint32le(test_buf + 0x18);
+
+    free(test_buf);
+
+    return (crc1 == test_crc1 && crc2 == test_crc2) ? 0 : 2;
+}
diff --git a/tools/telechips.h b/tools/telechips.h
index 27e133b..6550af7 100644
--- a/tools/telechips.h
+++ b/tools/telechips.h
@@ -24,5 +24,5 @@
 
 void telechips_encode_sum(unsigned char* buf, int length);
 void telechips_encode_crc(unsigned char* buf, int length);
-
+int telechips_test_crc(unsigned char* buf, int length);
 #endif