|
|
Wiki > Main > SbFileFormat (compare)
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Difference: SbFileFormat (r15 vs. r14)The sb format is used by most STMP chips to load the firmware. The format is different for different generations of chips. This page describes the sb format used by STMP 36xx and 37xx. It is used for example by Fuze+ (SansaFuzePlus). One can produce such a file using the elftosb2 program which can be found at Lyre project svn. The Rockbox svn also contains an open source implementation of elftosb2 (see /utils/sbtools/). The sbtoelf utility which can be found in the Rockbox svn (next to elftosb) is able to decrypt and extract data from a .sb file, and can repack the code in several ELF files. Format of the sb file. Everything is coded as little endian, even strings, except the "STMP" file magic. Global file formatThe .sb file consists of several blocks as show below
File header
The set of flags is as follows: bit 0 is display progress, bit 1 is verbose progress. Chunk headerChunk headers start at offset 0x60. Each chunk header is 16 bytes long and has the following structure. There are two types of chunks: boot sections and data sections.
See section about chunk data for more information about the content. Encryption dataThe elftosb2 program uses AES-128 in CBC mode. Internally, all important data is encrypted using a random key that will denote PK. This random key PK is written in an encrypted form in the sb file using the keys specified to the elftosb2 program. At this place of the file, the elftosb2 program outputs one 32 bytes value per key:
Notice that if there are several keys, it is possible to cross-check PK with the several keys. Final signatureThe final signature is a 32-bytes block. When decrypted using PK, it consists of the SHA-1 of the whole file (ie the encrypted file) except the last 32-bytes (of course); since the SHA-1 is 20-bytes long, it is padded with random data.
Chunk bodiesIn the fuze+ firmware file, the following chunks were found:
It is suspected that only boot sections are encrypted. A section is encrypted in AES-128 CBC mode using the PK key (see encryption data section) and the first 16-bytes of the sb header as IV (ie part of SHA-1 signature). The boot sections have a special format (when decrypted) to explain where load the instructions, which part of memory to fill and how to call functions. The format of the data sections has not been investigated. Boot section formatA boot section consist of a list of instruction. Each instruction starts with a 4-byte header with indicates what type of instruction it is. All values are in little-endian. All instruction are of size 16-bytes even, unused bytes are set to zero.
The checksum is computed this way. This is 90 plus the sum of all bytes of the instruction except the first one (to avoid circular reference), modulo 2^8=256. Here is an example:
We check that 0x4F = 90+(0x2+0x00+0x00)+(0x08+0x04+0x81+0x34)+(0x00+0x00+0x00+0x13)+(0x09+0x9b+0x99+0xe2) Nop instructionThe nop instruction terminates the boot section (it seems), it only consists of the header with opcode 0.
Tag instructionThe tag instruction has the opcode 1 1. It is probably used by the bootloader instead of chunk table. It precedes each section and has unknown format contains it identifier, length and semantics. flags.
Load instructionThe load instruction has the opcode 2 and is of variable size. It starts with a 16-byte header followed by some data. The header indicates the size of the data, the address at which to load it and include a CRC checksum.
The data is padded so next instruction will be aligned on a 16-byte boundary. The padding data is random and IS TAKEN INTO ACCOUNT in the CRC. The CRC is a classical CRC32 algorithm, the tables used can be found in the SVN. Fill instructionThe fill instruction has the opcode 3 and is of fixed size (16-bytes). The instruction indicates the size of memory range to fill, the starting address and the pattern.
Jump instructionThe jump instruction is the same as the call instruction (except for the semantics of course) and has opcode 4. Call instructionThe call instruction has opcode and has a calling address as well as a argument for the function.
Mode instructionThe mode instruction has opcode 6 . It is used to change the booting mode. The boot mode value matches the one in the datasheet. That one, the device can start booting from, say, i2c and has unknown format and semantics. then the i2c uses a mode command to boot from another device.
Encryption notesSee Block ciphers on wikipedia for more information on CBC mode. See CBC-MAC on wikipedia for more information on CBC-MAC. When nothing is said, it means the IV (Initialisation Vector) is taken to be 0. -- AmauryPouly - 26 Nov 2010 r18 - 30 Jan 2012 - 14:34:34 - AmauryPouly
Revision r15 - 19 Jun 2011 - 20:34 - AmauryPoulyRevision r14 - 17 Apr 2011 - 23:31 - AmauryPouly Copyright © by the contributing authors.
|