1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
26 #include "hmac-sha1.h"
28 static const char null_key_v1
[] = "CTL:N0MAD|PDE0.SIGN.";
29 static const char null_key_v2
[] = "CTL:N0MAD|PDE0.DPMP.";
30 static const char null_key_v3
[] = "CTL:Z3N07|PDE0.DPMP.";
31 static const char null_key_v4
[] = "CTL:N0MAD|PDE0.DPFP.";
33 static const unsigned char bootloader_v1
[] =
35 0xD3, 0xF0, 0x29, 0xE3, /* MSR CPSR_cf, #0xD3 */
36 0x09, 0xF6, 0xA0, 0xE3 /* MOV PC, #0x900000 */
39 static const unsigned char bootloader_v2
[] =
41 0xD3, 0xF0, 0x29, 0xE3, /* MSR CPSR_cf, #0xD3 */
42 0x09, 0xF6, 0xA0, 0xE3 /* MOV PC, #0x40000000 */
45 static const unsigned char bootloader_v3
[] =
50 static const struct device_info devices
[] =
52 /* Creative Zen Vision:M */
53 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M", 42, null_key_v2
, bootloader_v1
, sizeof(bootloader_v1
), 0x00900000},
54 /* Creative Zen Vision:M Go! */
55 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0:\0M\0 \0G\0o\0!", 50, null_key_v2
, bootloader_v1
, sizeof(bootloader_v1
), 0x00900000},
56 /* Creative Zen Vision © TL */
57 /* The "©" should be ANSI encoded or the device won't accept the firmware package. */
58 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0e\0n\0 \0V\0i\0s\0i\0o\0n\0 \0©\0T\0L", 46, null_key_v2
, bootloader_v1
, sizeof(bootloader_v1
), 0x00900000},
60 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N\0 \0V", 42, null_key_v4
, bootloader_v3
, sizeof(bootloader_v3
), 0x00000000},
62 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N", 48, null_key_v3
, bootloader_v2
, sizeof(bootloader_v2
), 0x40000000}
66 Create a Zen Vision:M FRESCUE structure file
68 extern void int2le(unsigned int val
, unsigned char* addr
);
69 extern unsigned int le2int(unsigned char* buf
);
72 static int make_ciff_file(unsigned char *inbuf
, unsigned int length
,
73 unsigned char *outbuf
, int device
)
75 unsigned char key
[20];
76 memcpy(outbuf
, "FFIC", 4);
77 int2le(length
+90, &outbuf
[4]);
78 memcpy(&outbuf
[8], "FNIC", 4);
79 int2le(96, &outbuf
[0xC]);
80 memcpy(&outbuf
[0x10], devices
[device
].cinf
, devices
[device
].cinf_size
);
81 memset(&outbuf
[0x10+devices
[device
].cinf_size
], 0,
82 96 - devices
[device
].cinf_size
);
83 memcpy(&outbuf
[0x70], "ATAD", 4);
84 int2le(length
+32, &outbuf
[0x74]);
85 memcpy(&outbuf
[0x78], "H\0j\0u\0k\0e\0b\0o\0x\0\x32\0.\0j\0r\0m",
86 32); /*Unicode encoded*/
87 memcpy(&outbuf
[0x98], inbuf
, length
);
88 memcpy(&outbuf
[0x98+length
], "LLUN", 4);
89 int2le(20, &outbuf
[0x98+length
+4]);
91 hmac_sha1((unsigned char *)devices
[device
].null
, strlen(devices
[device
].null
),
92 outbuf
, 0x98+length
, key
);
93 memcpy(&outbuf
[0x98+length
+8], key
, 20);
94 return length
+0x90+0x1C+8;
97 static int make_jrm_file(unsigned char *inbuf
, unsigned int length
,
98 unsigned char *outbuf
, int device
)
101 unsigned int sum
= 0;
103 /* Clear the header area to zero */
104 memset(outbuf
, 0, 0x18);
107 memcpy(outbuf
, "EDOC", 4);
109 #define SIZEOF_BOOTLOADER_CODE devices[device].bootloader_size
110 int2le(4+0xC+SIZEOF_BOOTLOADER_CODE
+0xC+length
, &outbuf
[0x4]);
111 /* 4 bytes of zero */
112 memset(&outbuf
[0x8], 0, 0x4);
114 /* First block starts here ... */
116 memset(&outbuf
[0xC], 0, 0x4);
118 int2le(SIZEOF_BOOTLOADER_CODE
, &outbuf
[0x10]);
120 for(i
=0; i
<SIZEOF_BOOTLOADER_CODE
; i
+= 4)
121 sum
+= le2int((unsigned char*)&devices
[device
].bootloader
[i
]) + (le2int((unsigned char*)&devices
[device
].bootloader
[i
])>>16);
122 int2le(sum
, &outbuf
[0x14]);
126 memcpy(&outbuf
[0x18], devices
[device
].bootloader
, SIZEOF_BOOTLOADER_CODE
);
128 /* Second block starts here ... */
129 /* Address = depends on target */
130 #define SB_START (0x18+SIZEOF_BOOTLOADER_CODE)
131 int2le(devices
[device
].memory_address
, &outbuf
[SB_START
]);
133 int2le(length
, &outbuf
[SB_START
+0x4]);
136 for(i
=0; i
<length
; i
+= 4)
137 sum
+= le2int(&inbuf
[i
]) + (le2int(&inbuf
[i
])>>16);
138 int2le(sum
, &outbuf
[SB_START
+0x8]);
139 outbuf
[SB_START
+0xA] = 0;
140 outbuf
[SB_START
+0xB] = 0;
142 memcpy(&outbuf
[SB_START
+0xC], inbuf
, length
);
144 return SB_START
+0xC+length
;
147 int zvm_encode(char *iname
, char *oname
, int device
)
152 unsigned char *outbuf
;
155 file
= fopen(iname
, "rb");
160 fseek(file
, 0, SEEK_END
);
161 length
= ftell(file
);
163 fseek(file
, 0, SEEK_SET
);
165 buf
= (unsigned char*)malloc(length
);
167 printf("out of memory!\n");
171 len
= fread(buf
, 1, length
, file
);
172 if(len
< (size_t)length
) {
178 outbuf
= (unsigned char*)malloc(length
+0x300);
181 printf("out of memory!\n");
184 length
= make_jrm_file(buf
, len
, outbuf
, device
);
186 buf
= (unsigned char*)malloc(length
+0x200);
187 memset(buf
, 0, length
+0x200);
188 length
= make_ciff_file(outbuf
, length
, buf
, device
);
191 file
= fopen(oname
, "wb");
198 len
= fwrite(buf
, 1, length
, file
);
199 if(len
< (size_t)length
) {