1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 by Maurus Cuelenaere
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 #include "hmac-sha1.h"
29 ---------------------------------------------------------------------------
30 Shamelessly taken from elf.h (for compatibility reasons included)
31 ---------------------------------------------------------------------------
33 This file defines standard ELF types, structures, and macros.
34 Copyright (C) 1995-2003,2004,2005,2006,2007 Free Software Foundation, Inc.
35 This file is part of the GNU C Library.
37 The GNU C Library is free software; you can redistribute it and/or
38 modify it under the terms of the GNU Lesser General Public
39 License as published by the Free Software Foundation; either
40 version 2.1 of the License, or (at your option) any later version.
42 The GNU C Library is distributed in the hope that it will be useful,
43 but WITHOUT ANY WARRANTY; without even the implied warranty of
44 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
45 Lesser General Public License for more details.
47 You should have received a copy of the GNU Lesser General Public
48 License along with the GNU C Library; if not, write to the Free
49 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
55 /* Type for a 16-bit quantity. */
56 typedef uint16_t Elf32_Half
;
58 /* Types for signed and unsigned 32-bit quantities. */
59 typedef uint32_t Elf32_Word
;
60 typedef int32_t Elf32_Sword
;
62 /* Types for signed and unsigned 64-bit quantities. */
63 typedef uint64_t Elf32_Xword
;
64 typedef int64_t Elf32_Sxword
;
66 /* Type of addresses. */
67 typedef uint32_t Elf32_Addr
;
69 /* Type of file offsets. */
70 typedef uint32_t Elf32_Off
;
72 /* Type for section indices, which are 16-bit quantities. */
73 typedef uint16_t Elf32_Section
;
75 #define EI_NIDENT (16)
79 unsigned char e_ident
[EI_NIDENT
]; /* Magic number and other info */
80 Elf32_Half e_type
; /* Object file type */
81 Elf32_Half e_machine
; /* Architecture */
82 Elf32_Word e_version
; /* Object file version */
83 Elf32_Addr e_entry
; /* Entry point virtual address */
84 Elf32_Off e_phoff
; /* Program header table file offset */
85 Elf32_Off e_shoff
; /* Section header table file offset */
86 Elf32_Word e_flags
; /* Processor-specific flags */
87 Elf32_Half e_ehsize
; /* ELF header size in bytes */
88 Elf32_Half e_phentsize
; /* Program header table entry size */
89 Elf32_Half e_phnum
; /* Program header table entry count */
90 Elf32_Half e_shentsize
; /* Section header table entry size */
91 Elf32_Half e_shnum
; /* Section header table entry count */
92 Elf32_Half e_shstrndx
; /* Section header string table index */
97 Elf32_Word sh_name
; /* Section name (string tbl index) */
98 Elf32_Word sh_type
; /* Section type */
99 Elf32_Word sh_flags
; /* Section flags */
100 Elf32_Addr sh_addr
; /* Section virtual addr at execution */
101 Elf32_Off sh_offset
; /* Section file offset */
102 Elf32_Word sh_size
; /* Section size in bytes */
103 Elf32_Word sh_link
; /* Link to another section */
104 Elf32_Word sh_info
; /* Additional section information */
105 Elf32_Word sh_addralign
; /* Section alignment */
106 Elf32_Word sh_entsize
; /* Entry size if section holds table */
109 #define ELFMAG0 0x7f /* Magic number byte 0 */
110 #define ELFMAG1 'E' /* Magic number byte 1 */
111 #define ELFMAG2 'L' /* Magic number byte 2 */
112 #define ELFMAG3 'F' /* Magic number byte 3 */
114 #define SHF_WRITE (1 << 0) /* Writable */
115 #define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
116 #define SHF_EXECINSTR (1 << 2) /* Executable */
118 #define SHT_NOBITS 8 /* Program space with no data (bss) */
121 ---------------------------------------------------------------------------
123 ---------------------------------------------------------------------------
126 static const char null_key_v1
[] = "CTL:N0MAD|PDE0.SIGN.";
127 static const char null_key_v2
[] = "CTL:N0MAD|PDE0.DPMP.";
128 static const char null_key_v3
[] = "CTL:Z3N07|PDE0.DPMP.";
129 static const char null_key_v4
[] = "CTL:N0MAD|PDE0.DPFP.";
131 static const struct device_info devices
[] =
133 /* Creative Zen Vision:M */
134 {"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
},
135 /* Creative Zen Vision:M Go! */
136 {"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
},
137 /* Creative Zen Vision © TL */
138 /* The "©" should be ANSI encoded or the device won't accept the firmware package. */
139 {"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
},
141 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N\0 \0V", 42, null_key_v4
},
143 {"C\0r\0e\0a\0t\0i\0v\0e\0 \0Z\0E\0N", 48, null_key_v3
}
147 Create a Zen Vision:M FRESCUE structure file
149 extern void int2le(unsigned int val
, unsigned char* addr
);
150 extern unsigned int le2int(unsigned char* buf
);
153 static int make_ciff_file(const unsigned char *inbuf
, unsigned int length
,
154 unsigned char *outbuf
, int device
)
156 unsigned char key
[20];
157 memcpy(outbuf
, "FFIC", 4);
158 int2le(length
+90, &outbuf
[4]);
159 memcpy(&outbuf
[8], "FNIC", 4);
160 int2le(96, &outbuf
[0xC]);
161 memcpy(&outbuf
[0x10], devices
[device
].cinf
, devices
[device
].cinf_size
);
162 memset(&outbuf
[0x10+devices
[device
].cinf_size
], 0,
163 96 - devices
[device
].cinf_size
);
164 memcpy(&outbuf
[0x70], "ATAD", 4);
165 int2le(length
+32, &outbuf
[0x74]);
166 memcpy(&outbuf
[0x78], "H\0j\0u\0k\0e\0b\0o\0x\0\x32\0.\0j\0r\0m",
167 25); /*Unicode encoded*/
168 memset(&outbuf
[0x78+25], 0, 32);
169 memcpy(&outbuf
[0x98], inbuf
, length
);
170 memcpy(&outbuf
[0x98+length
], "LLUN", 4);
171 int2le(20, &outbuf
[0x98+length
+4]);
173 hmac_sha1((unsigned char *)devices
[device
].null
, strlen(devices
[device
].null
),
174 outbuf
, 0x98+length
, key
);
175 memcpy(&outbuf
[0x98+length
+8], key
, 20);
176 return length
+0x90+0x1C+8;
179 static int elf_convert(const unsigned char *inbuf
, unsigned char *outbuf
)
181 Elf32_Ehdr
*main_header
;
182 Elf32_Shdr
*section_header
;
183 unsigned int i
, j
, sum
;
186 main_header
= (Elf32_Ehdr
*)inbuf
;
187 if( !( main_header
->e_ident
[0] == ELFMAG0
&& main_header
->e_ident
[1] == ELFMAG1
188 && main_header
->e_ident
[2] == ELFMAG2
&& main_header
->e_ident
[3] == ELFMAG3
) )
190 printf("Invalid ELF header!\n");
194 startaddr
= (intptr_t)outbuf
;
196 for(i
= 0; i
< main_header
->e_shnum
; i
++)
198 section_header
= (Elf32_Shdr
*)(inbuf
+main_header
->e_shoff
+i
*sizeof(Elf32_Shdr
));
200 if( (section_header
->sh_flags
& SHF_WRITE
|| section_header
->sh_flags
& SHF_ALLOC
201 || section_header
->sh_flags
& SHF_EXECINSTR
) && section_header
->sh_size
> 0
202 && section_header
->sh_type
!= SHT_NOBITS
)
205 int2le(section_header
->sh_addr
, outbuf
);
208 int2le(section_header
->sh_size
, outbuf
);
212 for(j
=0; j
<section_header
->sh_size
; j
+= 4)
213 sum
+= le2int((unsigned char*)(inbuf
+section_header
->sh_offset
+j
)) + (le2int((unsigned char*)(inbuf
+section_header
->sh_offset
+j
))>>16);
216 memset(outbuf
, 0, 2);
219 memcpy(outbuf
, inbuf
+section_header
->sh_offset
, section_header
->sh_size
);
220 outbuf
+= section_header
->sh_size
;
223 return (int)((intptr_t)outbuf
- startaddr
);
226 static int make_jrm_file(const unsigned char *inbuf
, unsigned char *outbuf
)
230 /* Clear the header area to zero */
231 memset(outbuf
, 0, 0x18);
234 memcpy(outbuf
, "EDOC", 4);
235 /* Total Size: temporarily set to 0 */
236 memset(&outbuf
[0x4], 0, 4);
237 /* 4 bytes of zero */
238 memset(&outbuf
[0x8], 0, 4);
240 length
= elf_convert(inbuf
, &outbuf
[0xC]);
243 /* Now set the actual Total Size */
244 int2le(4+length
, &outbuf
[0x4]);
249 int zvm_encode(const char *iname
, const char *oname
, int device
, bool enable_ciff
)
254 unsigned char *outbuf
;
257 file
= fopen(iname
, "rb");
263 fseek(file
, 0, SEEK_END
);
264 length
= ftell(file
);
266 fseek(file
, 0, SEEK_SET
);
268 buf
= (unsigned char*)malloc(length
);
271 printf("Out of memory!\n");
275 len
= fread(buf
, 1, length
, file
);
276 if(len
< (size_t)length
)
283 outbuf
= (unsigned char*)malloc(length
+0x300);
287 printf("Out of memory!\n");
290 length
= make_jrm_file(buf
, outbuf
);
295 printf("Error in making JRM file!\n");
300 buf
= (unsigned char*)malloc(length
+0x200);
304 printf("Out of memory!\n");
307 memset(buf
, 0, length
+0x200);
308 length
= make_ciff_file(outbuf
, length
, buf
, device
);
314 file
= fopen(oname
, "wb");
322 len
= fwrite(buf
, 1, length
, file
);
323 if(len
< (size_t)length
)