1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Dave Chapman
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 * CRC32 implementation taken from:
29 * efone - Distributed internet phone system.
31 * (c) 1999,2000 Krzysztof Dabrowski
32 * (c) 1999,2000 ElysiuM deeZine
34 * This program is free software; you can redistribute it and/or
35 * modify it under the terms of the GNU General Public License
36 * as published by the Free Software Foundation; either version
37 * 2 of the License, or (at your option) any later version.
41 /* based on implementation by Finn Yannick Jacobs */
46 /* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
47 * so make sure, you call it before using the other
50 static unsigned int crc_tab
[256];
52 /* chksum_crc() -- to a given block, this one calculates the
53 * crc32-checksum until the length is
54 * reached. the crc32-checksum will be
57 static unsigned int chksum_crc32 (unsigned char *block
, unsigned int length
)
59 register unsigned long crc
;
63 for (i
= 0; i
< length
; i
++)
65 crc
= ((crc
>> 8) & 0x00FFFFFF) ^ crc_tab
[(crc
^ *block
++) & 0xFF];
70 /* chksum_crc32gentab() -- to a global crc_tab[256], this one will
71 * calculate the crcTable for crc32-checksums.
72 * it is generated to the polynom [..]
75 static void chksum_crc32gentab (void)
77 unsigned long crc
, poly
;
81 for (i
= 0; i
< 256; i
++)
84 for (j
= 8; j
> 0; j
--)
88 crc
= (crc
>> 1) ^ poly
;
99 static void int2le(unsigned int val
, unsigned char* addr
)
101 addr
[0] = val
& 0xFF;
102 addr
[1] = (val
>> 8) & 0xff;
103 addr
[2] = (val
>> 16) & 0xff;
104 addr
[3] = (val
>> 24) & 0xff;
107 int mi4_encode(char *iname
, char *oname
, int version
, int magic
,
108 char *model
, char *type
)
114 unsigned int crc
= 0;
115 unsigned char *outbuf
;
117 file
= fopen(iname
, "rb");
122 fseek(file
,0,SEEK_END
);
123 length
= ftell(file
);
125 fseek(file
,0,SEEK_SET
);
127 /* Add 4 bytes to length (for magic), the 0x200 byte header and
128 then round to an even 0x400 bytes
130 mi4length
= (length
+4+0x200+0x3ff)&~0x3ff;
132 outbuf
= malloc(mi4length
);
135 printf("out of memory!\n");
139 /* Clear the buffer to zero */
140 memset(outbuf
, 0, mi4length
);
142 len
= fread(outbuf
+0x200, 1, length
, file
);
143 if(len
< (size_t)length
) {
149 /* We need to write some data into the actual image - before calculating
151 int2le(0x00000100, &outbuf
[0x2e0]); /* magic */
152 int2le(magic
, &outbuf
[0x2e4]); /* magic */
153 int2le(length
+4, &outbuf
[0x2e8]); /* length plus 0xaa55aa55 */
155 int2le(0xaa55aa55, &outbuf
[0x200+length
]); /* More Magic */
157 strncpy((char *)outbuf
+0x1f8, type
, 4); /* type of binary (RBBL, RBOS) */
158 strncpy((char *)outbuf
+0x1fc, model
, 4); /* 4 character model id */
160 /* Calculate CRC32 checksum */
161 chksum_crc32gentab ();
162 crc
= chksum_crc32 (outbuf
+0x200,mi4length
-0x200);
164 strncpy((char *)outbuf
, "PPOS", 4); /* Magic */
165 int2le(version
, &outbuf
[0x04]); /* .mi4 version */
166 int2le(length
+4, &outbuf
[0x08]); /* Length of firmware plus magic */
167 int2le(crc
, &outbuf
[0x0c]); /* CRC32 of mi4 file */
168 int2le(0x00000002, &outbuf
[0x10]); /* Encryption type: 2 = TEA */
169 int2le(mi4length
, &outbuf
[0x14]); /* Total .mi4 length */
170 int2le(mi4length
-0x200, &outbuf
[0x18]); /* Length of plaintext part */
172 /* v3 files require a dummy DSA signature */
173 if (version
== 0x00010301) {
177 file
= fopen(oname
, "wb");
183 len
= fwrite(outbuf
, 1, mi4length
, file
);
184 if(len
< (size_t)length
) {
191 fprintf(stderr
, "File encoded successfully\n" );