FreeCalypso > hg > freecalypso-reveng
view pirimei.c @ 59:3f38da3933c2
Pirelli's IMEI obfuscation cracked!
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 29 Nov 2013 00:39:02 +0000 |
parents | |
children |
line wrap: on
line source
/* * This program recovers the IMEI of a Pirelli DP-L10 phone from a dump of * its factory block (last 64 KiB sector of the 2nd flash chip select) and * the corresponding dieid file as written by fc-loadtool. * * The location of the 16-byte encrypted IMEI record within the factory block * (at offset 0x504) has been figured out with the help of the factdiff.c * program, and the magic decryption & verification algorithm has been found in * g23m/condat/com/src/comlib/cl_imei.c in the Leonardo semi-src by Sotovik. */ #include <sys/types.h> #include <openssl/des.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> DES_cblock ciphertext[2], dieid_key, decrypted[2]; DES_key_schedule keysched; read_ciphertext(filename) char *filename; { FILE *f; f = fopen(filename, "r"); if (!f) { perror(filename); exit(1); } fseek(f, 0x504L, 0); fread(ciphertext, 8, 2, f); fclose(f); } decode_hexdigit(ch) { if (isdigit(ch)) return(ch - '0'); else if (isalpha(ch)) return(ch - 'A' + 10); else return(ch - 'a' + 10); } read_dieid_file(filename) char *filename; { FILE *f; int i; char lb[64]; f = fopen(filename, "r"); if (!f) { perror(filename); exit(1); } for (i = 0; i < 4; i++) { fgets(lb, sizeof lb, f); if (!isxdigit(lb[0]) || !isxdigit(lb[1]) || !isxdigit(lb[2]) || !isxdigit(lb[3]) || !isxdigit(lb[4]) || !isxdigit(lb[5]) || !isxdigit(lb[6]) || !isxdigit(lb[7]) || lb[8] != ':' || lb[9] != ' ' || !isxdigit(lb[10]) || !isxdigit(lb[11]) || !isxdigit(lb[12]) || !isxdigit(lb[13]) || lb[14] != '\n') { fprintf(stderr, "%s, line %d: differs from expected\n", filename, i + 1); exit(1); } dieid_key[i*2] = (decode_hexdigit(lb[12]) << 4) | decode_hexdigit(lb[13]); dieid_key[i*2+1] = 0; } fclose(f); } print_des_cblock(msg, blk) char *msg; DES_cblock blk; { printf("%s: %02X %02X %02X %02X %02X %02X %02X %02X\n", msg, blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7]); } main(argc, argv) char **argv; { if (argc != 3) { fprintf(stderr, "usage: %s fact.bin dieid\n", argv[0]); exit(1); } read_ciphertext(argv[1]); read_dieid_file(argv[2]); print_des_cblock("Key derived from die ID", &dieid_key); print_des_cblock("Ciphertext block 1", &ciphertext[0]); print_des_cblock("Ciphertext block 2", &ciphertext[1]); DES_set_key_unchecked(&dieid_key, &keysched); DES_ecb_encrypt(&ciphertext[0], &decrypted[0], &keysched, DES_DECRYPT); print_des_cblock("1st decrypted block", &decrypted[0]); DES_ecb_encrypt(&ciphertext[1], &decrypted[1], &keysched, DES_DECRYPT); print_des_cblock("2nd decrypted block", &decrypted[1]); exit(0); }