Difference between revisions of "IPSF"

From The iPhone Wiki
Jump to: navigation, search
m (direct link)
 
Line 1: Line 1:
IPSF, or iPhone SIM Free, was the first software [[unlock]] available for the iPhone. It relied on two exploits, which weren't understood until much later. Both of these were only in [[Bootloader 3.9]]
+
IPSF, or iPhone SIM Free, was the first software [[unlock]] available for the iPhone. It relied on two exploits, which weren't understood until much later. Both of these were only in [[Baseband Bootloader|Bootloader 3.9]]
   
 
==RSA cube root==
 
==RSA cube root==

Latest revision as of 21:34, 28 October 2010

IPSF, or iPhone SIM Free, was the first software unlock available for the iPhone. It relied on two exploits, which weren't understood until much later. Both of these were only in Bootloader 3.9

RSA cube root

The first exploit discovered was an exploit in the parsing of decrypted RSA. The padding length just needed to be greater than 0xA. Since the decryption was done using exponent 3, you could create a plaintext message and take the cube root of it. The first 0x28 bytes would decrypt properly, enough to generate a valid token for 3.9.

This vulnerability in RSA was first discovered by Daniel Bleichenbacher in 2006. Bleichenbacher's RSA signature forgery based on implementation error

SHA1 zero

If the last 4 bytes in the SHA1 hash of the uploaded data were zero, the endpack would validate and the first 0x400 bytes would be written. This is a brilliant exploit since it isn't findable by reversing the IPSF software.

A loop is used to check if all five dwords (5 * 32 bits = 160 bits) of the SHA1 hash are equal to zero and pass the check if they are. This is because the SHA-1 bytes are initialized to zero for boot in "debug" mode, so the code is designed to handle that contingency. However, the code is badly designed:

u32 sha1[5];
for(i = 0; i < 5; i++) {
    bad = (sha1[i] != 0);
}

Instead of

u32 sha1[5];
for(i = 0; i < 5; i++) {
    if(sha1[i] != 0) {
        bad = true;
        break;
    }
}

This causes the bad == true if sha1[4] != 0 instead of bad == false if sha1[0] == 0 && sha1[1] == 0 && sha1[2] == 0 && sha1[3] == 0 && sha1[4] == 0.

Implementations