1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Telechips firmware checksum support for scramble
12 * Copyright (C) 2007 Dave Chapman
14 * Thanks to Hein-Pieter van Braam for his work in identifying the
17 * All files in this archive are subject to the GNU General Public License.
18 * See the file COPYING in the source tree root for full license agreement.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
27 #include <sys/types.h>
33 static uint32_t crctable
[256];
35 /* Simple implementation of a function to reverse the bottom n bits in x */
36 static uint32_t bitreverse(uint32_t x
,int n
)
39 uint32_t mask
= 1<<(n
-1);
53 /* Generate a lookup table for a reverse CRC32 */
54 static void gentable(uint32_t poly
)
60 for (index
= 0; index
< 256; index
++)
62 r
= bitreverse(index
,8) << 24;
70 crctable
[index
] = bitreverse(r
,32);
74 /* Perform a reverse CRC32 */
75 static uint32_t calc_crc(unsigned char *message
, int size
)
80 for (i
=0; i
< size
; i
++){
81 if ((i
< 0x10) || (i
>= 0x18)) {
82 crc
= crctable
[((crc
^ (message
[i
])) & 0xff)] ^ (crc
>> 8);
89 /* Endian-safe functions to read/write a 32-bit little-endian integer */
91 static uint32_t get_uint32le(unsigned char* p
)
93 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
96 static void put_uint32le(unsigned char* p
, uint32_t x
)
99 p
[1] = (x
>> 8) & 0xff;
100 p
[2] = (x
>> 16) & 0xff;
101 p
[3] = (x
>> 24) & 0xff;
104 /* A simple checksum - seems to be used by the TCC76x firmwares */
105 void telechips_encode_sum(unsigned char* buf
, int length
)
110 /* Set checksum field to 0 */
111 put_uint32le(buf
+ 0x10, 0);
113 /* Perform a simple sum, treating the file as a series of 32-bit
114 little-endian integers */
116 for (i
=0; i
< length
; i
+=4) {
117 sum
+= get_uint32le(buf
+ i
);
119 /* Negate the sum - this means that the sum of the whole file
120 (including this value) will be equal to zero */
123 /* Set the checksum field */
124 put_uint32le(buf
+ 0x10, sum
);
128 /* Two reverse CRC32 checksums - seems to be used by the TCC77x firmwares */
129 void telechips_encode_crc(unsigned char* buf
, int length
)
133 /* Generate the CRC table */
134 gentable(0x8001801BL
);
136 /* Clear the existing CRC values */
137 put_uint32le(buf
+0x10, 0);
138 put_uint32le(buf
+0x18, 0);
140 /* Write the length */
141 put_uint32le(buf
+0x1c, length
);
143 /* Calculate the first CRC - over the entire file */
144 crc1
= calc_crc(buf
, length
);
146 /* What happens next depends on the filesize */
147 if (length
>= 128*1024)
149 put_uint32le(buf
+0x18, crc1
);
151 crc2
= calc_crc(buf
, 128*1024);
152 put_uint32le(buf
+0x10, crc2
);
154 put_uint32le(buf
+0x10, crc1
);