iOS Dataprotection Basics

Keybags are an important part of iOS data protection, thought they are maybe the worst thing to deal with when installing multiple iOS instances on a single device. The process responsible of loading up the systembag is keybagd, one of the first daemon launched by launchd (after the kernel). It will checks if the system keybag, located in /var/keybags/systembag.kb, is valid. If the system keybag isn't valid, keybagd will end all running processes, set nvram auto-boot to false and reboot device. The device will then reboot in recovery mode. To create or update the systembag, iOS calls a framework called /System/Library/PrivateFrameworks/MobileKeyBag.framework/MobileKeyBag.

A keybag error usually happens for those cases:

When multibooting iOS versions which use the same keybag format, you can simply copy the systembag.kb file from the main OS data partition to the same directory in the secondary OS data partition and iOS should be able to boot fine. Both OS will use the same shared key in the effaceable-storage.

There are however some important considerations:

Those issues become way more complicated to deal with when multibooting iOS versions that use different keybag formats, for example iOS 7.x as main OS with 6.x or 5.x as secondary. In this case, we can't simply copy the systembag file between installed iOS versions because they aren't in the same format. Older iOS versions will fail to load the newer systembag formats.

Instead, we will have to generate a new systembag on the other installed iOS versions. The MobileKeyBag.framework creates the systembag according to the current framework version (which changes from an iOS version to another). For example, we want to dual-boot iOS 7.1.2 as main OS with iOS 6.1.3 as secondary OS. Copying the iOS 7.1.2 systembag to the iOS 6.1.3 data partition will most likely make iOS 6.1.3 fails to boot with a kb_load() error because iOS 6.1.3 keybagd can't load iOS 7.1.2 keybag format. Regenerating an iOS 6.x type keybag during the secondary OS boot will works, but you will get a bootloop when you will reboot to your main OS since the effaceable-storage key has been overwritten when the iOS 6.x keybag was created. We must find a way to regenerate a keybag during the secondary OS boot without touching the effaceable-storage. A special attribute called no-effaceable-storage in the DeviceTree image can tell the MobileKeyBag framework to do this. A fake key will be used instead of the one in BAG1 (effaceable storage). This will allow generating a new systembag according to the keybag version supported by the installed iOS. Another interest of this patch is that everytime the framework is called, it will still use a fake key. This means that device passcode can be changed without caring about bootloops. To prevent MobileKeyBag.framework from generating a new key in effaceable-storage, we must add the no-effaceable-storage node in devicetree image.

> Part 7: Patch DeviceTree