Difference between revisions of "GIDecrypt"

From The iPhone Wiki
Jump to: navigation, search
m (Gidecrypt moved to GIDecrypt: looks cooler)
Line 1: Line 1:
 
This is a quick and simple program I wrote to automatically decrypt [[KBAG]] and print the key/iv pair for a given 3.0 IMG3. This hasn't been throughly tested on anything other then 32bit linux, so there might be some bugs. I figured since this was already out in the open, I might as well make it easier for everybody. Also, this requires libcrypto to compile properly.
 
This is a quick and simple program I wrote to automatically decrypt [[KBAG]] and print the key/iv pair for a given 3.0 IMG3. This hasn't been throughly tested on anything other then 32bit linux, so there might be some bugs. I figured since this was already out in the open, I might as well make it easier for everybody. Also, this requires libcrypto to compile properly.
   
  +
== License ==
<pre>
 
  +
This code is assumed to be in the public domain. As it uses OpenSSL, this code CAN NOT be used in GNU GPL applications<sup>[<!---->[http://www.gnu.org/licenses/license-list.html#OpenSSL 1]<!---->]</sup>. It can, however, be used in GNU GPL applications IF [http://gnutls.org GnuTLS] is used instead as GnuTLS is licensed under the GNU LGPL, which is GNU GPL compatible.
/*
 
* gidecrypt.c
 
*
 
* Created on: Jun 17, 2009
 
* Author: posixninja
 
*/
 
#include <stdio.h>
 
#include <string.h>
 
#include <stdlib.h>
 
#include <openssl/aes.h>
 
   
  +
The [[#Code|code]] below requires OpenSSL, but can support GnuTLS with very little modification
typedef struct {
 
unsigned int magic;
 
unsigned int total_size;
 
unsigned int data_size;
 
unsigned int state;
 
unsigned int type;
 
unsigned char iv[16];
 
unsigned char key[32];
 
} kbag_struct;
 
   
  +
== Code ==
void hexdump(unsigned char* hex, int size) {
 
  +
/*
int i = 0;
 
  +
* gidecrypt.c
for (i = 0; i < size; i++) {
 
  +
*
printf("%02x", hex[i]);
 
  +
* Created on: Jun 17, 2009
}
 
  +
* Author: posixninja
printf("\n");
 
  +
*
}
 
  +
* Modified on: Jan 23, 2013
 
  +
* Author: 5urd
int main(int argc, char* argv[]) {
 
  +
*/
unsigned char gid_key[] = { 0x5F, 0x65, 0x02, 0x95, 0xE1, 0xFF, 0xFC, 0x97,
 
  +
#include <stdio.h>
0xCE, 0x77, 0xAB, 0xD4, 0x9D, 0xD9, 0x55, 0xB3 };
 
  +
#include <string.h>
unsigned char gid_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
  +
#include <stdlib.h>
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
  +
#include <stdint.h>
 
  +
#include <openssl/aes.h>
unsigned char kbag_tag[4] = { 0x47, 0x41, 0x42, 0x4B };
 
  +
unsigned char outbuf[32];
 
  +
typedef struct {
char* input;
 
  +
uint32_t magic;
char* output;
 
  +
uint32_t total_size;
 
  +
uint32_t data_size;
if (argc <= 1) {
 
  +
uint32_t state;
printf("Usage: ./gidecrypt <input.img3>\n");
 
return 1;
+
uint32_t type;
  +
uint8_t iv[16];
}
 
  +
} kbag_struct;
output = argv[2];
 
  +
 
  +
void hexdump(uint8_t* hex, int size) {
FILE* in_file = fopen(input, "rb");
 
if (in_file == NULL) {
+
int i = 0;
printf("Can't open file %s\n", input);
+
for (i = 0; i < size; i++)
  +
printf("%02x", hex[i]);
return 1;
 
  +
printf("\n");
}
 
  +
}
fseek(in_file, 0, SEEK_END);
 
  +
int file_size = ftell(in_file);
 
  +
int main(int argc, char* argv[]) {
fseek(in_file, 0, SEEK_SET);
 
  +
uint8_t gid_key[] = { 0x5F, 0x65, 0x02, 0x95, 0xE1, 0xFF, 0xFC, 0x97,
 
  +
0xCE, 0x77, 0xAB, 0xD4, 0x9D, 0xD9, 0x55, 0xB3 };
unsigned char* file_buffer = malloc(file_size);
 
  +
uint8_t gid_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
fread(file_buffer, 1, file_size, in_file);
 
  +
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
fclose(in_file);
 
  +
 
  +
uint8_t kbag_tag[4] = { 0x47, 0x41, 0x42, 0x4B };
int i = 0;
 
  +
uint8_t outbuf[32];
kbag_struct* kbag;
 
  +
uint8_t* input;
for (i = 0; i < file_size; i++) {
 
  +
uint8_t* output;
if (memcmp(&file_buffer[i], &kbag_tag, 4) == 0) {
 
  +
AES_KEY aeskey;
kbag = malloc(sizeof(kbag_struct));
 
  +
kbag_struct* kbag;
memcpy(kbag, &file_buffer[i], sizeof(kbag_struct));
 
  +
int file_size;
}
 
  +
 
  +
if (argc < 3) {
AES_KEY aeskey;
 
  +
printf("Usage: ./gidecrypt <input.img3> <output.img3>\n");
AES_set_decrypt_key(gid_key, kbag->type ,&aeskey);
 
  +
return 1;
AES_cbc_encrypt((unsigned char*)&kbag->iv, outbuf, 0x30, &aeskey, gid_iv, AES_DECRYPT);
 
  +
}
 
  +
input = argv[1];
printf("IV: ");
 
  +
output = argv[2];
hexdump(outbuf, 16);
 
  +
printf("Key: ");
 
  +
FILE* in_file = fopen(input, "rb");
hexdump(&outbuf[16], 16);
 
  +
if (in_file == NULL) {
 
  +
printf("Can't open file %s\n", input);
free(kbag);
 
  +
return 1;
free(file_buffer);
 
return 0;
+
}
  +
fseek(in_file, 0, SEEK_END);
}
 
  +
file_size = ftell(in_file);
</pre>
 
input = argv[1];
+
uint8_t key[32];
break;
+
uint8_t* file_buffer;
}
+
int i;
  +
fseek(in_file, 0, SEEK_SET);
  +
  +
file_buffer = malloc(file_size);
  +
fread(file_buffer, 1, file_size, in_file);
  +
fclose(in_file);
  +
  +
for (i = 0; i < file_size; i++) {
  +
if (memcmp(&file_buffer[i], &kbag_tag, 4) == 0) {
  +
kbag = malloc(sizeof(kbag_struct));
  +
memcpy(kbag, &file_buffer[i], sizeof(kbag_struct));
  +
break;
  +
}
  +
}
  +
  +
AES_set_decrypt_key(gid_key, kbag->type ,&aeskey);
  +
AES_cbc_encrypt((unsigned char*)&kbag->iv, outbuf, 0x30, &aeskey, gid_iv, AES_DECRYPT);
  +
  +
printf("IV: ");
  +
hexdump(outbuf, 16);
  +
printf("Key: ");
  +
hexdump(&outbuf[16], 16);
  +
  +
free(kbag);
  +
free(file_buffer);
  +
  +
return 0;
  +
}

Revision as of 01:55, 24 January 2013

This is a quick and simple program I wrote to automatically decrypt KBAG and print the key/iv pair for a given 3.0 IMG3. This hasn't been throughly tested on anything other then 32bit linux, so there might be some bugs. I figured since this was already out in the open, I might as well make it easier for everybody. Also, this requires libcrypto to compile properly.

License

This code is assumed to be in the public domain. As it uses OpenSSL, this code CAN NOT be used in GNU GPL applications[1]. It can, however, be used in GNU GPL applications IF GnuTLS is used instead as GnuTLS is licensed under the GNU LGPL, which is GNU GPL compatible.

The code below requires OpenSSL, but can support GnuTLS with very little modification

Code

/*
 * gidecrypt.c
 *
 *  Created on: Jun 17, 2009
 *      Author: posixninja
 * 
 *  Modified on: Jan 23, 2013
 *      Author: 5urd
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <openssl/aes.h>

typedef struct {
    uint32_t magic;
    uint32_t total_size;
    uint32_t data_size;
    uint32_t state;
    uint32_t type;
    uint8_t iv[16];
    uint8_t key[32];
} kbag_struct;

void hexdump(uint8_t* hex, int size) {
    int i = 0;
    for (i = 0; i < size; i++)
        printf("%02x", hex[i]);
    printf("\n");
}

int main(int argc, char* argv[]) {
    uint8_t gid_key[] = { 0x5F, 0x65, 0x02, 0x95, 0xE1, 0xFF, 0xFC, 0x97,
                          0xCE, 0x77, 0xAB, 0xD4, 0x9D, 0xD9, 0x55, 0xB3 };
    uint8_t gid_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    
    uint8_t kbag_tag[4] = { 0x47, 0x41, 0x42, 0x4B };
    uint8_t outbuf[32];
    uint8_t* input;
    uint8_t* output;
    AES_KEY aeskey;
    kbag_struct* kbag;
    uint8_t* file_buffer;
    int i;
    int file_size;
    
    if (argc < 3) {
        printf("Usage: ./gidecrypt <input.img3> <output.img3>\n");
        return 1;
    }
    input = argv[1];
    output = argv[2];

    FILE* in_file = fopen(input, "rb");
    if (in_file == NULL) {
        printf("Can't open file %s\n", input);
        return 1;
    }
    fseek(in_file, 0, SEEK_END);
    file_size = ftell(in_file);
    fseek(in_file, 0, SEEK_SET);

    file_buffer = malloc(file_size);
    fread(file_buffer, 1, file_size, in_file);
    fclose(in_file);
    
    for (i = 0; i < file_size; i++) {
        if (memcmp(&file_buffer[i], &kbag_tag, 4) == 0) {
            kbag = malloc(sizeof(kbag_struct));
            memcpy(kbag, &file_buffer[i], sizeof(kbag_struct));
            break;
        }
    }
    
    AES_set_decrypt_key(gid_key, kbag->type ,&aeskey);
    AES_cbc_encrypt((unsigned char*)&kbag->iv, outbuf, 0x30, &aeskey, gid_iv, AES_DECRYPT);
    
    printf("IV:  ");
    hexdump(outbuf, 16);
    printf("Key: ");
    hexdump(&outbuf[16], 16);
    
    free(kbag);
    free(file_buffer);
    
    return 0;
}