IMG1: Difference between revisions

From freemyipod
Jump to navigation Jump to search
No edit summary
No edit summary
 
(15 intermediate revisions by 4 users not shown)
Line 5: Line 5:
It is sometimes called the '8900' image, which is how it was called on the original iPhone / S5L8900. It is also sometimes called the 'DFU image' format (because it's used in DFU mode to load WTF).
It is sometimes called the '8900' image, which is how it was called on the original iPhone / S5L8900. It is also sometimes called the 'DFU image' format (because it's used in DFU mode to load WTF).


The iPhone Wiki has some basic [https://www.theiphonewiki.com/wiki/S5L_File_Formats#8900 information about the format]. However, that only describes the '1.0' version of IMG1. The lineage of IMG1 has continued in iPods long after iOS-based devices stopped its use, with IMG2/IMG3 never making it to the newer non-Touch iPods. Here we describe the known usage of IMG1, including its 2.0 version, in clickwheel iPods and non-iBoot bootroms.
The Apple Wiki has some basic [https://theapplewiki.com/wiki/S5L_File_Formats#8900 information about the format]. However, that only describes the '1.0' version of IMG1. The lineage of IMG1 has continued in iPods long after iOS-based devices stopped its use, with IMG2/IMG3 never making it to the newer non-Touch iPods. Here we describe the known usage of IMG1, including its 2.0 version, in clickwheel iPods and non-iBoot bootroms.


== Header Format ==
== Header Format ==


   struct IMG1_20 {
   struct IMG1 {
     char magic[4];         // SoC digits, eg. `8720`.
     u8  magic[4];           // 0x0, SoC digits, eg. `8720`.
     char version[3];       // `1.0` or `2.0`
     u8  version[3];         // 0x4, `1.0` or `2.0`
     byte format;           // Encryption/signature format. See below.
     u8  format;             // 0x7, Encryption/signature format. See below.
     uint entrypoint;       // Offset to jump to within body (after header).
     u32 entrypoint;         // 0x8, Offset to jump to within body (after header).
     uint bodyLen;           // Size of the image body, ie. the data loaded into memory, before the
     u32 bodyLength;         // 0xC, Size of the image body, i.e. the data loaded into memory, before the
                            // signature/certificates start, after the header.
                            // signature/certificates start, after the header.
     uint dataLen;           // Size of everything that's not the header (body + signature + certificates).
     u32 dataLength;         // 0x10, Size of everything that's not the header (body + signature + certificates).
     uint footerCertOffset; // Offset of certificate start (after header).
     u32 footerCertOffset;   // 0x14, Offset of certificate start (after header).
     uint footerCertLen;     // Size of certificate bundle.
     u32 footerCertLength;   // 0x18, Size of certificate bundle.
     byte salt[32];         // Random data.
     u8  salt[32];           // 0x1C, Random data.
     ushort unk1;
     u16 unk1;               // 0x3C
     ushort unk2;           // Security epoch?
     u16 securityEpoch;       // 0x3E, Security epoch?
     byte headerSign[16];   // AES-encrypted SHA1 signature of everything up to headerSign.
     u8  headerSignature[16]; // 0x40, AES-encrypted SHA1 signature of everything up to headerSignature.
     byte headerLeftover[4]; // Last four bytes of unencrypted SHA1, usually leftover in images, but not
     u8  headerLeftover[4];   // 0x50, Last four bytes of unencrypted SHA1, usually leftover in images, but not
                            // checked by firmware. Curiosity.
                            // checked by firmware. Curiosity.
   }
   }


The header is padded to either 0x600 (S5L8720) or 0x400 (S5L8740) bytes. The different sections are a bit tricky to reason about, there's an attempted overview:
The body is padded to either 0x800 (S5L8900 (iOS)/S5L8702), 0x600 (S5L8720/S5L8930) or 0x400 (S5L8723/S5L8740) bytes. The different sections are a bit tricky to reason about, here's an attempted overview:


   0:    Header (0x40 + 0x14 bytes, first 0x40 signed into last 0x14 bytes)
   0:    Header (0x40 + 0x14 bytes, first 0x40 signed into last 0x14 bytes)
   0x54:  Padding until $header_size (magic dependent, 0x600 in this example)  
   0x54:  Padding until $header_size (magic dependent, 0x600 in this example)  
   0x600: Body, bodyLen bytes.
   0x600: Body, bodyLength bytes.
   ...
   ...
   0x600 + bodyLen: body signature (for X509 formats)
   0x600 + bodyLength: body signature (for X509 formats)
   0x680 + bodyLen (also 0x600+footerCertLen): certificate bundle (for X509 formats)
   0x680 + bodyLength (also 0x600+footerCertLength): certificate bundle (for X509 formats)
   0x680 + bodyLen + footerCertLen: end of file.
   0x680 + bodyLength + footerCertLength: end of file.


The body signature is always 0x80 bytes long, and its length is not counted into bodyLen or footerCertLen.
The body signature is always 0x80 bytes long, and its length is not counted into bodyLength or footerCertLength.


A few assertions should hold:
A few assertions should hold for non-Touch iPods:


# File size == $header_size + bodyLen + footerCertLen + 0x80
# File size == $header_size + bodyLength + footerCertLength + 0x80
# dataLen = bodyLen + 0x80 + footerCertLen
# dataLength = bodyLength + 0x80 + footerCertLength
 
It is worth noting that for early iOS devices, dataLength is actually the offset to the body signature. It is unknown why Apple has changed this to the data length.


=== Encryption/Signature Formats ===
=== Encryption/Signature Formats ===
Line 59: Line 61:
|}
|}


DFU mode in N3G,N4G,N5G seems only accepts X509_SIGNED_ENCRYPTED.
DFU mode in [[Nano_3G]], [[Nano_4G]], [[Nano_5G]] seems to only accept X509_SIGNED_ENCRYPTED.


Other boot modes (notably in N3G) seem to accept other formats, but that's to be verified. N4G+/2.0 do not accept any non-X509 formats.
Other boot modes (notably in [[Nano_3G]]) seem to accept other formats, but that's to be verified. [[Nano_4G]] and later i.e. 2.0 don't accept any non-X509 formats.
 
The rsrc images in the [[Nano_3G]] and [[Nano_4G]] firmware are not IMG1 - they have a 0x00/0xFF header/padding, then the body starts, and there's no certificate/signature, just 0x00 padding at the end. On [[Nano_5G]], [[Nano_6G]] and [[Nano_7G]] the rsrc image is actually an IMG1, and the only X509_SIGNED image seen in iPod firmware so far.


=== Differences between v1.0 and 2.0 ===
=== Differences between v1.0 and 2.0 ===


Nano4G+ use 2.0. Everything else uses 1.0.
[[Nano_4G]] and later use 2.0. Everything else uses 1.0.


1.0 bootroms supports encryption formats 1,2, 3 and 4. 2.0 only supports encryption formats 3 and 4.
1.0 bootroms support encryption formats 1, 2, 3 and 4. 2.0 only supports encryption formats 3 and 4.


When uploading IMG1 images via DFU, 1.0 images need to be suffixed with a CRC32 of their content. 2.0 images don't need the CRC32.
When uploading IMG1 images via DFU, 1.0 images need to be suffixed with a CRC32 of their content. 2.0 images don't need the CRC32.
Line 85: Line 89:
   // data is ready, ship it!
   // data is ready, ship it!


Because after the 0x10 bytes of the AES-encrypted SHA1 signature, there are 4 bytes of unencrypted SHA1 (because a SHA1 digest is 0x14 bytes, while an AES128 block is 0x10 bytes). This means that you can check the header signature yourself (or, well, 32 bits of the signature) by performing the following:
As after the 0x10 bytes of the AES-encrypted SHA1 signature, there are 4 bytes of unencrypted SHA1 (because a SHA1 digest is 0x14 bytes, while an AES128 block is 0x10 bytes). This means that you can check the header signature yourself (or, well, 32 bits of the signature) by performing the following:


   sha1s(data[0:0x40]).digest()[-4:] == data[0x50:0x54]
   sha1(data[0:0x40]).digest()[-4:] == data[0x50:0x54]


This has likely zero security implications, but is nonetheless a fascinating curiosity.
This has likely zero security implications, but is nonetheless a fascinating curiosity.
== Verification Routine ==
There are 2 signatures that are verified by the loader (BootROM or LLB/WTF), those being the header signature and the body signature.
The header signature in full is verified by taking the SHA1 digest of data[0:0x40], encrypting it with the Global/GID key, and comparing it with the signature contained in the header.
The body signature is verified by first finding the leaf certificate, taking the public key from it, then verifying the body signature with the body data (defined as data[bodyPad:bodyPad + bodyLength]) and the public key.
The certificate bundle is verified by ensuring the leaf certificate in the chain has a serial starting with <code>01:fb:01:fb</code> (production devices, dev devices) or <code>01:fb:00:fb</code> (dev devices). The root certificate in the chain must have a SHA fingerprint that matches one hardcoded in the BootROM (<code>61:1e:5b:66:2c:59:3a:08:ff:58:d1:4a:e2:24:52:d1:98:df:6c:60</code>, Apple Root CA). In addition, string comparisons are performed against the root and leaf subject CNs.
== Parsing Decrypted IMG1 Files ==
With the development of the [[wInd3x]] exploit and its [https://github.com/freemyipod/wInd3x implementation] it has become possible to decrypt IMG1 files on the [[Nano_4G]] and [[Nano_5G]]. The [[Nano_4G]] has two separate sets of firmware available, firmware intended to interface with the [[Nano_4G]] hardware through DFU mode to assist with the restoration of the iPod to factory settings and the general retail firmware that is intended to be used by the consumer. Both sets of firmware can be obtained by following the links available [https://itunes.apple.com/WebObjects/MZStore.woa/wa/com.apple.jingle.appserver.client.MZITunesClientCheck/version?touchUpdate=true here]. In particular the `x12250000_Recovery.ipsw` file contains the WTF firmware (WTF.x1225.release.dfu) that interacts with DFU mode and the `iPod_31.1.0.4.ipsw` contains the bootloader (N58s.bootloader.release.rb3) and the rest of the [[RetailOS]].
To assist with development for the [[Nano_4G]] hardware, it is important to understand the drivers that are included in these IMG1 files.
These drivers are included as part of the (U)EFI image that is contained within the IMG1 file.
For the [[Nano_4G]], the first 0x700 bytes of the IMG1 contains a header that is discussed above. The rest of the file contains what seems to be a UEFI firmware partition. Some of the information about UEFI firmware from the [https://en.wikipedia.org/wiki/UEFI Wikipedia page] seems relevant to understand this partition as well as the [https://wiki.osdev.org/UEFI OS Dev wiki page on UEFI development], which discusses UEFI applications and seems to be the format for some of the files included within the IMG1 volume.
Using The uefi-firmware-parser package [https://github.com/theopolis/uefi-firmware-parser available here], it is possible to extract the files in this EFI volume. The files in the partition can be extracted by removing the first 0x700 bytes ([[Nano_4G]]) of the decrypted IMG1 file. This can be done with a hex editor or other tools. Furthermore, this step can be skipped if the option `-b` is used below. It is also recommended to set up a separate Conda environment to use with this tool. The files can be extracted as follows:
  uefi-firmware-parser -o out/ -e decrypted_efi_firmware_filename_here
The benefit of this approach is this will extract all drivers included in the EFI firmware volume and also decompress each driver. The next step in the process is to identify the function of each driver. For this Apple was helpful enough to not strip out the name of each driver inside each driver file. The mapping from the file GUIDs to their functions can be recovered in many ways, but here is a simple script to print out the mapping:
  for ii in `find out/ | grep "\.pe"`;
    do echo $ii | cut -d '/' -f 3 | cut -d '-' -f 2-;
    strings $ii | tail -n 1 | rev | cut -d '/' -f 1 | rev| cut -d '.' -f 1;
    echo;
  done
There is an additional .te file that contains the executable code that is jumped to from Secure Boot.
The extracted firmware PE files will contain a valid PE file header and will begin with the "MZ" magic bytes. It may be helpful to use [https://github.com/blackberry/pe_tree PE Tree] to parse these headers and inspect these files. Manual inspection with a hex editor can be done as well. Some information about PE file headers is available [https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers here].
The above instructions assume a [[Nano_4G]] IMG1 WTF file or Bootloader. See [https://github.com/freemyipod/defs/blob/main/efi.py here] for more information about the [[Nano_5G]] IMG1 structure.

Latest revision as of 01:15, 25 August 2026

Introduction

IMG1 is a pseudonym for the image format used by early iOS devices and all S5L-based iPods.

It is sometimes called the '8900' image, which is how it was called on the original iPhone / S5L8900. It is also sometimes called the 'DFU image' format (because it's used in DFU mode to load WTF).

The Apple Wiki has some basic information about the format. However, that only describes the '1.0' version of IMG1. The lineage of IMG1 has continued in iPods long after iOS-based devices stopped its use, with IMG2/IMG3 never making it to the newer non-Touch iPods. Here we describe the known usage of IMG1, including its 2.0 version, in clickwheel iPods and non-iBoot bootroms.

Header Format

 struct IMG1 {
   u8  magic[4];            // 0x0, SoC digits, eg. `8720`.
   u8  version[3];          // 0x4, `1.0` or `2.0`
   u8  format;              // 0x7, Encryption/signature format. See below.
   u32 entrypoint;          // 0x8, Offset to jump to within body (after header).
   u32 bodyLength;          // 0xC, Size of the image body, i.e. the data loaded into memory, before the
                            // signature/certificates start, after the header.
   u32 dataLength;          // 0x10, Size of everything that's not the header (body + signature + certificates).
   u32 footerCertOffset;    // 0x14, Offset of certificate start (after header).
   u32 footerCertLength;    // 0x18, Size of certificate bundle.
   u8  salt[32];            // 0x1C, Random data.
   u16 unk1;                // 0x3C
   u16 securityEpoch;       // 0x3E, Security epoch?
   u8  headerSignature[16]; // 0x40, AES-encrypted SHA1 signature of everything up to headerSignature.
   u8  headerLeftover[4];   // 0x50, Last four bytes of unencrypted SHA1, usually leftover in images, but not
                            // checked by firmware. Curiosity.
 }

The body is padded to either 0x800 (S5L8900 (iOS)/S5L8702), 0x600 (S5L8720/S5L8930) or 0x400 (S5L8723/S5L8740) bytes. The different sections are a bit tricky to reason about, here's an attempted overview:

 0:     Header (0x40 + 0x14 bytes, first 0x40 signed into last 0x14 bytes)
 0x54:  Padding until $header_size (magic dependent, 0x600 in this example) 
 0x600: Body, bodyLength bytes.
 ...
 0x600 + bodyLength: body signature (for X509 formats)
 0x680 + bodyLength (also 0x600+footerCertLength): certificate bundle (for X509 formats)
 0x680 + bodyLength + footerCertLength: end of file.

The body signature is always 0x80 bytes long, and its length is not counted into bodyLength or footerCertLength.

A few assertions should hold for non-Touch iPods:

  1. File size == $header_size + bodyLength + footerCertLength + 0x80
  2. dataLength = bodyLength + 0x80 + footerCertLength

It is worth noting that for early iOS devices, dataLength is actually the offset to the body signature. It is unknown why Apple has changed this to the data length.

Encryption/Signature Formats

Format (number) Header signed (SHA1+AES) Body encrypted Body signed (X509/RSA) AES Operation Notes
SIGNED_ENCRYPTED (1) Encryption, Global/GID Key Not accepted in 2.0.
SIGNED (2) Encryption, Global/GID Key Not accepted in 2.0.
X509_SIGNED_ENCRYPTED (3) Decryption, Global/GID Key Most (all?) released images have this type
X509_SIGNED (4) Decryption, Global/GID Key

DFU mode in iPod nano (3rd generation), iPod nano (4th generation), iPod nano (5th generation) seems to only accept X509_SIGNED_ENCRYPTED.

Other boot modes (notably in iPod nano (3rd generation)) seem to accept other formats, but that's to be verified. iPod nano (4th generation) and later i.e. 2.0 don't accept any non-X509 formats.

The rsrc images in the iPod nano (3rd generation) and iPod nano (4th generation) firmware are not IMG1 - they have a 0x00/0xFF header/padding, then the body starts, and there's no certificate/signature, just 0x00 padding at the end. On iPod nano (5th generation), iPod nano (6th generation) and iPod nano (7th generation) the rsrc image is actually an IMG1, and the only X509_SIGNED image seen in iPod firmware so far.

Differences between v1.0 and 2.0

iPod nano (4th generation) and later use 2.0. Everything else uses 1.0.

1.0 bootroms support encryption formats 1, 2, 3 and 4. 2.0 only supports encryption formats 3 and 4.

When uploading IMG1 images via DFU, 1.0 images need to be suffixed with a CRC32 of their content. 2.0 images don't need the CRC32.

Differences between iBoot/SecureROM and iPod images

The iPod images do not use 'Key 0x837', and in fact use the Global/GID key for all AES operations.

The iPod images are sometimes decrypted using the encrypt direction of the AES engine (formats 1 and 2) and sometimes with the decrypt direction of the AES engine (formats 3 and 4). iBoot/SecureROM images seem to all use the decrypt direction.

Leftover SHA in header

It seems like whatever generates IMG1 images does so in the following pseudocode:

 sha1(src=data, srcLen=0x40, dst=data+0x40)
 aes(src=data+0x40, size=0x10)
 // data is ready, ship it!

As after the 0x10 bytes of the AES-encrypted SHA1 signature, there are 4 bytes of unencrypted SHA1 (because a SHA1 digest is 0x14 bytes, while an AES128 block is 0x10 bytes). This means that you can check the header signature yourself (or, well, 32 bits of the signature) by performing the following:

 sha1(data[0:0x40]).digest()[-4:] == data[0x50:0x54]

This has likely zero security implications, but is nonetheless a fascinating curiosity.

Verification Routine

There are 2 signatures that are verified by the loader (BootROM or LLB/WTF), those being the header signature and the body signature.

The header signature in full is verified by taking the SHA1 digest of data[0:0x40], encrypting it with the Global/GID key, and comparing it with the signature contained in the header.

The body signature is verified by first finding the leaf certificate, taking the public key from it, then verifying the body signature with the body data (defined as data[bodyPad:bodyPad + bodyLength]) and the public key.

The certificate bundle is verified by ensuring the leaf certificate in the chain has a serial starting with 01:fb:01:fb (production devices, dev devices) or 01:fb:00:fb (dev devices). The root certificate in the chain must have a SHA fingerprint that matches one hardcoded in the BootROM (61:1e:5b:66:2c:59:3a:08:ff:58:d1:4a:e2:24:52:d1:98:df:6c:60, Apple Root CA). In addition, string comparisons are performed against the root and leaf subject CNs.

Parsing Decrypted IMG1 Files

With the development of the wInd3x exploit and its implementation it has become possible to decrypt IMG1 files on the iPod nano (4th generation) and iPod nano (5th generation). The iPod nano (4th generation) has two separate sets of firmware available, firmware intended to interface with the iPod nano (4th generation) hardware through DFU mode to assist with the restoration of the iPod to factory settings and the general retail firmware that is intended to be used by the consumer. Both sets of firmware can be obtained by following the links available here. In particular the `x12250000_Recovery.ipsw` file contains the WTF firmware (WTF.x1225.release.dfu) that interacts with DFU mode and the `iPod_31.1.0.4.ipsw` contains the bootloader (N58s.bootloader.release.rb3) and the rest of the retailOS.

To assist with development for the iPod nano (4th generation) hardware, it is important to understand the drivers that are included in these IMG1 files.

These drivers are included as part of the (U)EFI image that is contained within the IMG1 file.

For the iPod nano (4th generation), the first 0x700 bytes of the IMG1 contains a header that is discussed above. The rest of the file contains what seems to be a UEFI firmware partition. Some of the information about UEFI firmware from the Wikipedia page seems relevant to understand this partition as well as the OS Dev wiki page on UEFI development, which discusses UEFI applications and seems to be the format for some of the files included within the IMG1 volume.

Using The uefi-firmware-parser package available here, it is possible to extract the files in this EFI volume. The files in the partition can be extracted by removing the first 0x700 bytes (iPod nano (4th generation)) of the decrypted IMG1 file. This can be done with a hex editor or other tools. Furthermore, this step can be skipped if the option `-b` is used below. It is also recommended to set up a separate Conda environment to use with this tool. The files can be extracted as follows:

 uefi-firmware-parser -o out/ -e decrypted_efi_firmware_filename_here

The benefit of this approach is this will extract all drivers included in the EFI firmware volume and also decompress each driver. The next step in the process is to identify the function of each driver. For this Apple was helpful enough to not strip out the name of each driver inside each driver file. The mapping from the file GUIDs to their functions can be recovered in many ways, but here is a simple script to print out the mapping:

 for ii in `find out/ | grep "\.pe"`;
   do echo $ii | cut -d '/' -f 3 | cut -d '-' -f 2-; 
   strings $ii | tail -n 1 | rev | cut -d '/' -f 1 | rev| cut -d '.' -f 1;
   echo; 
 done

There is an additional .te file that contains the executable code that is jumped to from Secure Boot.

The extracted firmware PE files will contain a valid PE file header and will begin with the "MZ" magic bytes. It may be helpful to use PE Tree to parse these headers and inspect these files. Manual inspection with a hex editor can be done as well. Some information about PE file headers is available here.

The above instructions assume a iPod nano (4th generation) IMG1 WTF file or Bootloader. See here for more information about the iPod nano (5th generation) IMG1 structure.