The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "GIDecrypt"
Posixninja (talk | contribs) m (and perfectionist) |
m |
||
(8 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | + | '''GIDecrypt''' is a program written by [[User:posixninja|p0sixninja]] to automatically decrypt [[KBAG]] and print the key/IV pair for a given 3.0 IMG3. |
|
+ | Tested on anything other then 32-bit Linux. Requires libcrypto to compile properly. |
||
− | <pre> |
||
− | /* |
||
− | * gidecrypt.c |
||
− | * |
||
− | * Created on: Jun 17, 2009 |
||
− | * Author: posixninja |
||
− | */ |
||
− | #include <stdio.h> |
||
− | #include <string.h> |
||
− | #include <stdlib.h> |
||
− | #include <openssl/aes.h> |
||
+ | == License == |
||
− | typedef struct { |
||
+ | This code is assumed to be in the public domain, or where that is not possible, this code is [http://creativecommons.org/choose/zero/ CC0]. As it uses OpenSSL, this code CAN NOT be used in GNU GPL applications<sup>1</sup>, however, this statement has been disputed and there are ways around this restriction<sup>2</sup>. It can, however, be used freely 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. |
||
− | 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; |
||
+ | The [[#Code|code]] below requires OpenSSL, but can support GnuTLS with very little modification |
||
− | void hexdump(unsigned char* hex, int size) { |
||
− | int i = 0; |
||
− | for (i = 0; i < size; i++) { |
||
− | printf("%02x", hex[i]); |
||
− | } |
||
− | printf("\n"); |
||
− | } |
||
+ | == Code == |
||
− | int main(int argc, char* argv[]) { |
||
+ | /* |
||
− | unsigned char gid_key[] = { 0x5F, 0x65, 0x02, 0x95, 0xE1, 0xFF, 0xFC, 0x97, |
||
+ | * gidecrypt.c |
||
− | 0xCE, 0x77, 0xAB, 0xD4, 0x9D, 0xD9, 0x55, 0xB3 }; |
||
+ | * |
||
− | unsigned char gid_iv[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
||
+ | * Created on: Jun 17, 2009 |
||
− | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
||
+ | * 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 < 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 aes_key; |
||
+ | kbag_struct *kbag; |
||
+ | uint8_t *file_buffer; |
||
+ | int i; |
||
+ | int file_size; |
||
+ | FILE *in_file; |
||
+ | |||
+ | if (argc < 3) { |
||
+ | printf("Usage: ./gidecrypt <input.img3> <output.img3>\n"); |
||
+ | return 1; |
||
+ | } |
||
+ | input = argv[1]; |
||
+ | output = argv[2]; |
||
+ | |||
+ | 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 ,&aes_key); |
||
+ | AES_cbc_encrypt((uint8_t*)&kbag->iv, outbuf, 0x30, &aes_key, gid_iv, AES_DECRYPT); |
||
+ | |||
+ | printf("IV: "); |
||
+ | hexdump(outbuf, 16); |
||
+ | printf("Key: "); |
||
+ | hexdump(&outbuf[16], 16); |
||
+ | |||
+ | free(kbag); |
||
+ | free(file_buffer); |
||
+ | |||
+ | return 0; |
||
+ | } |
||
+ | == References == |
||
− | unsigned char kbag_tag[4] = { 0x47, 0x41, 0x42, 0x4B }; |
||
+ | # [http://www.gnu.org/licenses/license-list.html#OpenSSL Why the GNU GPL is incompatible with OpenSSL] |
||
− | unsigned char outbuf[32]; |
||
+ | # [http://www.gnome.org/ GNOME] on [http://people.gnome.org/~markmc/openssl-and-the-gpl.html OpenSSL and the GPL] |
||
− | char* input; |
||
− | char* output; |
||
+ | [[Category:Decryption]] |
||
− | if (argc <= 1) { |
||
− | printf("Usage: ./gidecrypt <input.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); |
||
− | int file_size = ftell(in_file); |
||
− | fseek(in_file, 0, SEEK_SET); |
||
− | |||
− | unsigned char* file_buffer = malloc(file_size); |
||
− | fread(file_buffer, 1, file_size, in_file); |
||
− | fclose(in_file); |
||
− | |||
− | int i = 0; |
||
− | kbag_struct* kbag; |
||
− | 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_KEY aeskey; |
||
− | 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; |
||
− | } |
||
− | </pre> |
Latest revision as of 18:25, 9 March 2017
GIDecrypt is a program written by p0sixninja to automatically decrypt KBAG and print the key/IV pair for a given 3.0 IMG3.
Tested on anything other then 32-bit Linux. Requires libcrypto to compile properly.
License
This code is assumed to be in the public domain, or where that is not possible, this code is CC0. As it uses OpenSSL, this code CAN NOT be used in GNU GPL applications1, however, this statement has been disputed and there are ways around this restriction2. It can, however, be used freely 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 < 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 aes_key; kbag_struct *kbag; uint8_t *file_buffer; int i; int file_size; FILE *in_file; if (argc < 3) { printf("Usage: ./gidecrypt <input.img3> <output.img3>\n"); return 1; } input = argv[1]; output = argv[2]; 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 ,&aes_key); AES_cbc_encrypt((uint8_t*)&kbag->iv, outbuf, 0x30, &aes_key, gid_iv, AES_DECRYPT); printf("IV: "); hexdump(outbuf, 16); printf("Key: "); hexdump(&outbuf[16], 16); free(kbag); free(file_buffer); return 0; }