Difference between revisions of "KBAG"

From The iPhone Wiki
Jump to: navigation, search
(KBAG Format)
m (Fix spelling & make consistant)
(30 intermediate revisions by 10 users not shown)
Line 1: Line 1:
  +
Apple's [[IMG3 File Format|IMG3]] and [[IMG4 File Format|IMG4]] security scheme uses a data format called a '''KBAG'''. At the bottom of a firmware file, you will see something that will, on the ASCII side of your hex editor, say "GABK", which, as ARM is [[wikipedia:little-endian|little-endian]] based, is "KBAG" flipped. Look on the hex side and you will see the KBAG according to this format:
==Explanation==
 
  +
In Apple's new IMG3 security scheme, they have used something called a KBAG. At the bottom of a firmware file, you will see something that will, on the ASCII side of your hex editor, see "GABK", which is "KBAG" flipped. Look on the hex side and you will the KBAG according to this format:
 
  +
== How it works ==
  +
It boils down to using the [[GID Key]] to decrypt <code>encIV</code> and <code>encKey</code>, then using that key and IV to decrypt the DATA section of the file (the code itself).
  +
  +
Because of the circumstances with the [[IMG3 File Format]], the kernel never needs to even touch the [[GID Key]] anymore, as its job is to just flash the image to the [[NOR]] as is, with container and all.
  +
  +
In order to decrypt the KBAG for img3, you need to remove them using this command: <code>dd if=IMG3_FILE bs=1 skip=4741424B count=0x70</code> or for img4, <code>dd if=IMG4FILE bs=44 skip=1 | openssl enc -aes-256-cbc -d -nopad -iv IV -K KEY > OUTPUTFILE</code>
  +
  +
To grab the KBAG for img3 files, you'd run <code>xpwntool /path/to/img3/ /dev/null</code>.
  +
  +
This is different with img4 files. For these, you can use [https://github.com/xerub/img4lib img4lib] and run the following command: <code>img4 -i /path/to/image.im4p -b</code>.
   
 
==KBAG Format==
 
==KBAG Format==
 
===KBAG128===
 
===KBAG128===
  +
typedef struct Unparsed_KBAG_AES128 {
<pre>
 
  +
uint32_t magic; // string with bytes flipped ("KBAG" in little endian)
typedef struct Unparsed_KBAG_128 {
 
  +
uint32_t fullSize; // size of KBAG from beyond that point to the end of it
char[4] magic; // string with bits flipped = "KBAG" (magic = 0x4741424B)
 
int fullSize; // size of KBAG from beyond that point to the end of it
+
uint32_t tagDataSize; // size of KBAG without this 0xC header
  +
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]]
int unk1; // 8 less than fullSize. not sure what it is exactly.
 
int AES_Type; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
+
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
char[16] Enc_IV; // IV for the firmware file, encrypted with the gid key
+
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]]
char[16] Enc_Key; // Key for the firmware file, encrypted with the gid key.
+
uint8_t encKey[16]; // Key for the firmware file, encrypted with the [[GID Key]]
  +
} UnparsedKbagAes128_t;
} Unparsed_KBAG_AES128;
 
int IV_Key_Crypt_state; // 1 if the key and IV in the KBAG are encrypted with the GID key, 0 if not.
+
// 2 is used with a second KBAG for the [[S5L8920]], use is unknown.
</pre>
 
   
 
===KBAG192===
 
===KBAG192===
  +
typedef struct Unparsed_KBAG_AES192 {
<pre>
 
  +
uint32_t magic; // string with bytes flipped ("KBAG" in little endian)
typedef struct Unparsed_KBAG_AES192 {
 
  +
uint32_t fullSize; // size of KBAG from beyond that point to the end of it
char[4] magic; // string with bits flipped = "KBAG" (magic = 0x4741424B)
 
int fullSize; // size of KBAG from beyond that point to the end of it
+
uint32_t tagDataSize; // size of KBAG without this 0xC header
  +
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]]
int unk1; // 8 less than fullSize. not sure what it is exactly.
 
int AES_Type; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
+
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
char[16] Enc_IV; // IV for the firmware file, encrypted with the gid key
+
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]]
char[24] Enc_Key; // Key for the firmware file, encrypted with the gid key.
+
uint8_t encKey[24]; // Key for the firmware file, encrypted with the [[GID Key]]
  +
} UnparsedKbagAes192_t;
} Unparsed_KBAG_AES192;
 
int IV_Key_Crypt_state; // 1 if the key and IV in the KBAG are encrypted with the GID key, 0 if not.
+
// 2 is used with a second KBAG for the [[S5L8920]], use is unknown.
</pre>
 
   
===KBAG256====
+
===KBAG256===
  +
typedef struct Unparsed_KBAG_256 {
<pre>
 
  +
uint32_t magic; // string with bytes flipped ("KBAG" in little endian)
typedef struct Unparsed_KBAG_256 {
 
  +
uint32_t fullSize; // size of KBAG from beyond that point to the end of it
char[4] magic; // string with bits flipped = "KBAG" (magic = 0x4741424B)
 
  +
uint32_t cryptState; // 1 if the key and IV in the KBAG are encrypted with the [[GID Key]]
int unk1; // 8 less than fullSize. not sure what it is exactly.
 
int IV_Key_Crypt_state; // 1 if the key and IV in the KBAG are encrypted with the GID key, 0 if not.
+
// 2 is used with a second KBAG for the [[S5L8920]], use is unknown.
int AES_Type; // 0x80 = aes-128, 0xc0 = aes-192, 0x100 = aes256
+
uint32_t aesType; // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
char[16] Enc_IV; // IV for the firmware file, encrypted with the gid key
+
uint8_t encIV[16]; // IV for the firmware file, encrypted with the [[GID Key]]
char[32] Enc_Key; // Key for the firmware file, encrypted with the gid key.
+
uint8_t encKey[32]; // Key for the firmware file, encrypted with the [[GID Key]]
  +
} UnparsedKbagAes256_t;
} Unparsed_KBAG_AES256;
 
int fullSize; // size of KBAG from beyond that point to the end of it
+
uint32_t tagDataSize; // size of KBAG without this 0xC header
</pre>
 
   
=How it works=
 
Basically, it just boils down to using the iPhone / iPod group id key to decrypt Enc_IV and Enc_Key, then using that key and IV to decrypt the DATA section of the file (the code itself).
 
   
  +
[[Category:Firmware Tags]]
As an interesting side note, because of the circumstances with the IMG3 format, the Kernel never needs to even touch the gid key anymore, as it's job it to just flash the image to the NOR as is, with container and all.
 

Revision as of 20:26, 16 March 2020

Apple's IMG3 and IMG4 security scheme uses a data format called a KBAG. At the bottom of a firmware file, you will see something that will, on the ASCII side of your hex editor, say "GABK", which, as ARM is little-endian based, is "KBAG" flipped. Look on the hex side and you will see the KBAG according to this format:

How it works

It boils down to using the GID Key to decrypt encIV and encKey, then using that key and IV to decrypt the DATA section of the file (the code itself).

Because of the circumstances with the IMG3 File Format, the kernel never needs to even touch the GID Key anymore, as its job is to just flash the image to the NOR as is, with container and all.

In order to decrypt the KBAG for img3, you need to remove them using this command: dd if=IMG3_FILE bs=1 skip=4741424B count=0x70 or for img4, dd if=IMG4FILE bs=44 skip=1 | openssl enc -aes-256-cbc -d -nopad -iv IV -K KEY > OUTPUTFILE

To grab the KBAG for img3 files, you'd run xpwntool /path/to/img3/ /dev/null.

This is different with img4 files. For these, you can use img4lib and run the following command: img4 -i /path/to/image.im4p -b.

KBAG Format

KBAG128

typedef struct Unparsed_KBAG_AES128 {
     uint32_t magic;       // string with bytes flipped ("KBAG" in little endian)
     uint32_t fullSize;    // size of KBAG from beyond that point to the end of it
     uint32_t tagDataSize; // size of KBAG without this 0xC header
     uint32_t cryptState;  // 1 if the key and IV in the KBAG are encrypted with the GID Key
                           // 2 is used with a second KBAG for the S5L8920, use is unknown.
     uint32_t aesType;     // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
     uint8_t encIV[16];    // IV for the firmware file, encrypted with the GID Key
     uint8_t encKey[16];   // Key for the firmware file, encrypted with the GID Key
} UnparsedKbagAes128_t;

KBAG192

typedef struct Unparsed_KBAG_AES192 {
     uint32_t magic;       // string with bytes flipped ("KBAG" in little endian)
     uint32_t fullSize;    // size of KBAG from beyond that point to the end of it
     uint32_t tagDataSize; // size of KBAG without this 0xC header
     uint32_t cryptState;  // 1 if the key and IV in the KBAG are encrypted with the GID Key
                           // 2 is used with a second KBAG for the S5L8920, use is unknown.
     uint32_t aesType;     // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
     uint8_t encIV[16];    // IV for the firmware file, encrypted with the GID Key
     uint8_t encKey[24];   // Key for the firmware file, encrypted with the GID Key
} UnparsedKbagAes192_t;

KBAG256

typedef struct Unparsed_KBAG_256 {
     uint32_t magic;       // string with bytes flipped ("KBAG" in little endian)
     uint32_t fullSize;    // size of KBAG from beyond that point to the end of it
     uint32_t tagDataSize; // size of KBAG without this 0xC header
     uint32_t cryptState;  // 1 if the key and IV in the KBAG are encrypted with the GID Key
                           // 2 is used with a second KBAG for the S5L8920, use is unknown.
     uint32_t aesType;     // 0x80 = aes128 / 0xc0 = aes192 / 0x100 = aes256
     uint8_t encIV[16];    // IV for the firmware file, encrypted with the GID Key
     uint8_t encKey[32];   // Key for the firmware file, encrypted with the GID Key
} UnparsedKbagAes256_t;