Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

restore: Add support for updating AppleTCON #158

Merged
merged 1 commit into from
Oct 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pymobiledevice3/restore/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
71: 'INSTALLING_RECOVERY_OS_IMAGE',
74: 'REQUESTING_EAN_DATA',
77: 'SEALING_SYSTEM_VOLUME',
81: 'UPDATING_APPLETCON',
}
SUPPORTED_DATA_TYPES = {
'BasebandBootData': False,
Expand Down
3 changes: 2 additions & 1 deletion pymobiledevice3/restore/ipsw/build_identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def populate_tss_request_parameters(self, parameters):
'BbActivationManifestKeyHash', 'BbCalibrationManifestKeyHash',
'BbFactoryActivationManifestKeyHash', 'BbFDRSecurityKeyHash', 'BbSkeyId', 'SE,ChipID',
'Savage,ChipID', 'Savage,PatchEpoch', 'Yonkers,BoardID', 'Yonkers,ChipID',
'Yonkers,PatchEpoch', 'Rap,BoardID', 'Rap,ChipID', 'Rap,SecurityDomain', 'eUICC,ChipID',
'Yonkers,PatchEpoch', 'Rap,BoardID', 'Rap,ChipID', 'Rap,SecurityDomain', 'Baobab,BoardID',
'Baobab,ChipID', 'Baobab,ManifestEpoch', 'Baobab,SecurityDomain', 'eUICC,ChipID',
'PearlCertificationRootPub', 'Manifest')

for k in keys_to_copy:
Expand Down
33 changes: 33 additions & 0 deletions pymobiledevice3/restore/restore.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,34 @@ def get_veridian_firmware_data(self, info: Mapping):

return response

def get_tcon_firmware_data(self, info: Mapping):
logging.info(f'restore_get_tcon_firmware_data: {info}')
comp_name = 'Baobab,TCON'

# create Baobab request
request = TSSRequest()
parameters = dict()

# add manifest for current build_identity to parameters
self.build_identity.populate_tss_request_parameters(parameters)

# add Baobab,* tags from info dictionary to parameters
parameters.update(info)

# add required tags for Baobab TSS request
request.add_tcon_tags(parameters, None)

logging.info('Sending Baobab TSS request...')
response = request.send_receive()

ticket = response.get('Baobab,Ticket')
if ticket is None:
logging.warning('No "Baobab,Ticket" in TSS response, this might not work')

response['FirmwareData'] = self.build_identity.get_component(comp_name).data

return response

def send_firmware_updater_data(self, message: Mapping):
logging.debug(f'got FirmwareUpdaterData request: {message}')
arguments = message['Arguments']
Expand Down Expand Up @@ -811,6 +839,11 @@ def send_firmware_updater_data(self, message: Mapping):
if fwdict is None:
raise PyMobileDevice3Exception(f'Couldn\'t get Veridian firmware data')

elif updater_name == 'AppleTCON':
fwdict = self.get_tcon_firmware_data(info)
if fwdict is None:
raise PyMobileDevice3Exception(f'Couldn\'t get TCON firmware data')

else:
raise PyMobileDevice3Exception(f'Got unknown updater name: {updater_name}')

Expand Down
45 changes: 45 additions & 0 deletions pymobiledevice3/restore/tss.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,51 @@ def add_veridian_tags(self, parameters: typing.Mapping, overrides: typing.Mappin
if overrides is not None:
self._request.update(overrides)

def add_tcon_tags(self, parameters: typing.Mapping, overrides: typing.Mapping = None):
manifest = parameters['Manifest']

# add tags indicating we want to get the Baobab,Ticket
self._request['@BBTicket'] = True
self._request['@Baobab,Ticket'] = True

keys_to_copy_uint = ('Baobab,BoardID', 'Baobab,ChipID', 'Baobab,Life', 'Baobab,ManifestEpoch',
'Baobab,SecurityDomain',)

for key in keys_to_copy_uint:
value = get_with_or_without_comma(parameters, key)

if isinstance(value, bytes):
self._request[key] = bytes_to_uint(value)
else:
self._request[key] = value

isprod = bool(get_with_or_without_comma(parameters, 'Baobab,ProductionMode', False))
self._request['Baobab,ProductionMode'] = isprod

nonce = get_with_or_without_comma(parameters, 'Baobab,UpdateNonce')

if nonce is not None:
self._request['Baobab,UpdateNonce'] = nonce

ecid = get_with_or_without_comma(parameters, 'Baobab,ECID')

if ecid is not None:
self._request['Baobab,ECID'] = ecid

for comp_name, node in manifest.items():
if not comp_name.startswith('Baobab,'):
continue

manifest_entry = dict(node)
manifest_entry.pop('Info')
manifest_entry['EPRO'] = isprod

# finally add entry to request
self._request[comp_name] = manifest_entry

if overrides is not None:
self._request.update(overrides)

def img4_create_local_manifest(self, build_identity=None):
manifest = None
if build_identity is not None:
Expand Down