diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common.h | 8 | ||||
| -rw-r--r-- | src/dfu.c | 17 | ||||
| -rw-r--r-- | src/dfu.h | 1 | ||||
| -rw-r--r-- | src/idevicerestore.c | 24 | ||||
| -rw-r--r-- | src/idevicerestore.h | 1 | ||||
| -rw-r--r-- | src/normal.c | 45 | ||||
| -rw-r--r-- | src/normal.h | 1 | ||||
| -rw-r--r-- | src/recovery.c | 16 | ||||
| -rw-r--r-- | src/recovery.h | 1 | 
9 files changed, 113 insertions, 1 deletions
| diff --git a/src/common.h b/src/common.h index a634e6f..2ea4a91 100644 --- a/src/common.h +++ b/src/common.h @@ -42,6 +42,13 @@ extern "C" {  #define FLAG_QUIT            1 +#define CPFM_FLAG_SECURITY_MODE 1 << 0 +#define CPFM_FLAG_PRODUCTION_MODE 1 << 1 + +#define IBOOT_FLAG_IMAGE4_AWARE  1 << 2 +#define IBOOT_FLAG_EFFECTIVE_SECURITY_MODE 1 << 3 +#define IBOOT_FLAG_EFFECTIVE_PRODUCTION_MODE 1 << 4 +  struct dfu_client_t;  struct normal_client_t;  struct restore_client_t; @@ -70,6 +77,7 @@ struct idevicerestore_client_t {  	uint64_t ecid;  	unsigned char* nonce;  	int nonce_size; +	int image4supported;  	char* udid;  	char* srnm;  	char* ipsw; @@ -241,6 +241,22 @@ int dfu_get_cpid(struct idevicerestore_client_t* client, unsigned int* cpid) {  	return 0;  } +int dfu_is_image4_supported(struct idevicerestore_client_t* client) +{ +	if(client->dfu == NULL) { +		if (dfu_client_new(client) < 0) { +			return 0; +		} +	} + +	const struct irecv_device_info *device_info = irecv_get_device_info(client->dfu->client); +	if (!device_info) { +		return 0; +	} + +	return (device_info->ibfl & IBOOT_FLAG_IMAGE4_AWARE); +} +  int dfu_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size) {  	irecv_error_t dfu_error = IRECV_E_SUCCESS; @@ -250,7 +266,6 @@ int dfu_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** non  		}  	} -  	const struct irecv_device_info *device_info = irecv_get_device_info(client->dfu->client);  	if (!device_info) {  		return -1; @@ -44,6 +44,7 @@ const char* dfu_check_product_type(struct idevicerestore_client_t* client);  int dfu_send_buffer(struct idevicerestore_client_t* client, unsigned char* buffer, unsigned int size);  int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_identity, const char* component);  int dfu_get_cpid(struct idevicerestore_client_t* client, unsigned int* cpid); +int dfu_is_image4_supported(struct idevicerestore_client_t* client);  int dfu_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size);  int dfu_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size);  int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_identity); diff --git a/src/idevicerestore.c b/src/idevicerestore.c index e9580bd..a0f5a87 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -365,6 +365,9 @@ int idevicerestore_start(struct idevicerestore_client_t* client)  	info("Product Version: %s\n", client->version);  	info("Product Build: %s Major: %d\n", client->build, client->build_major); +	client->image4supported = is_image4_supported(client); +	info("Device supports Image4: %s\n", (client->image4supported) ? "true" : "false"); +  	if (client->flags & FLAG_CUSTOM) {  		/* prevent signing custom firmware */  		tss_enabled = 0; @@ -1182,6 +1185,27 @@ const char* check_product_type(struct idevicerestore_client_t* client) {  	return product_type;  } +int is_image4_supported(struct idevicerestore_client_t* client) +{ +	int res = 0; + +	switch (client->mode->index) { +	case MODE_NORMAL: +		res = normal_is_image4_supported(client); +		break; +	case MODE_DFU: +		res = dfu_is_image4_supported(client); +		break; +	case MODE_RECOVERY: +		res = recovery_is_image4_supported(client); +		break; +	default: +		error("ERROR: Device is in an invalid state\n"); +		return 0; +	} +	return res; +} +  int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {  	switch (client->mode->index) {  	case MODE_NORMAL: diff --git a/src/idevicerestore.h b/src/idevicerestore.h index c7ac7f9..f646d4a 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -75,6 +75,7 @@ void usage(int argc, char* argv[]);  int check_mode(struct idevicerestore_client_t* client);  const char* check_product_type(struct idevicerestore_client_t* client);  int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); +int is_image4_supported(struct idevicerestore_client_t* client);  int get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size);  int get_shsh_blobs(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss);  void fixup_tss(plist_t tss); diff --git a/src/normal.c b/src/normal.c index 15bbc01..3b536ed 100644 --- a/src/normal.c +++ b/src/normal.c @@ -391,6 +391,51 @@ int normal_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char**  	return normal_get_nonce_by_key(client, "SEPNonce", nonce, nonce_size);  } +int normal_is_image4_supported(struct idevicerestore_client_t* client) +{ +	idevice_t device = NULL; +	plist_t node = NULL; +	lockdownd_client_t lockdown = NULL; +	idevice_error_t device_error = IDEVICE_E_SUCCESS; +	lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; + +	device_error = idevice_new(&device, client->udid); +	if (device_error != IDEVICE_E_SUCCESS) { +		return 0; +	} + +	lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		error("ERROR: Unable to connect to lockdownd\n"); +		idevice_free(device); +		return 0; +	} + +	lockdown_error = lockdownd_get_value(lockdown, NULL, "Image4Supported", &node); +	if (lockdown_error != LOCKDOWN_E_SUCCESS) { +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return 0; +	} + +	if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { +		lockdownd_client_free(lockdown); +		idevice_free(device); +		return 0; +	} + +	uint8_t bval = 0; +	plist_get_bool_val(node, &bval); +	plist_free(node); + +	lockdownd_client_free(lockdown); +	idevice_free(device); +	lockdown = NULL; +	device = NULL; + +	return bval; +} +  int normal_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {  	idevice_t device = NULL;  	plist_t unique_chip_node = NULL; diff --git a/src/normal.h b/src/normal.h index 892747a..abc4fe1 100644 --- a/src/normal.h +++ b/src/normal.h @@ -47,6 +47,7 @@ void normal_client_free(struct idevicerestore_client_t* client);  int normal_open_with_timeout(struct idevicerestore_client_t* client);  int normal_enter_recovery(struct idevicerestore_client_t* client);  int normal_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); +int normal_is_image4_supported(struct idevicerestore_client_t* client);  int normal_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size);  int normal_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); diff --git a/src/recovery.c b/src/recovery.c index f2104b7..9221dda 100644 --- a/src/recovery.c +++ b/src/recovery.c @@ -461,6 +461,22 @@ int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {  	return 0;  } +int recovery_is_image4_supported(struct idevicerestore_client_t* client) +{ +	if(client->recovery == NULL) { +		if (recovery_client_new(client) < 0) { +			return 0; +		} +	} + +	const struct irecv_device_info *device_info = irecv_get_device_info(client->recovery->client); +	if (!device_info) { +		return 0; +	} + +	return (device_info->ibfl & IBOOT_FLAG_IMAGE4_AWARE); +} +  int recovery_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size) {  	irecv_error_t recovery_error = IRECV_E_SUCCESS; diff --git a/src/recovery.h b/src/recovery.h index 8deb438..7da2432 100644 --- a/src/recovery.h +++ b/src/recovery.h @@ -54,6 +54,7 @@ int recovery_send_reset(struct idevicerestore_client_t* client);  int recovery_send_ticket(struct idevicerestore_client_t* client);  int recovery_set_autoboot(struct idevicerestore_client_t* client, int enable);  int recovery_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid); +int recovery_is_image4_supported(struct idevicerestore_client_t* client);  int recovery_get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size);  int recovery_get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); | 
