Core OS • iOS • 53:38
Securing data is an important feature of any application. Learn how to use the Keychain and get recipes to protect application data. Understand how to determine data caching policies, what to do when a device locks, and how to handle upgrades and restores of iPhone OS devices.
Speakers: John Wright, Mitch Adler
Unlisted on Apple Developer site
Downloads from Apple
Transcript
This transcript has potential transcription errors. We are working on an improved version.
[John Wright]
Hello, everyone. My name is John Wright. I'm part of Platform Technologies in Core OS. We're responsible for a lot of the security infrastructure in iOS. And today, we're going to talk about-- a little bit about protecting data on the phone. So we're going to go over-- this is our agenda. So first, I'm going to talk a little bit about what data protection is and what security mechanisms we have in place in iOS and kind of how they've evolved over the different releases.
And then we're going to kind of do a deep dive into the design of our data protection mechanisms, and this is more for your security analysis. This is not something that you actually need to know. It's all done under the covers. But I think a lot of you that are kind of in the trust-but-verify hats, really want to know this information.
Then we're going to talk a little bit about enabling data protection, both from a user standpoint and from an enterprised standpoint of managing a device. And then we're going to talk a little bit about the API's that you-- that we want you to adopt in your applications to be in data protection and how to protect your user's data.
So these devices that we have, these phones and iPads and iPod touches, they're very personal devices, and they have a lot of-- more data on them than we've ever had before ringing around people's pockets. And one of the things that is kind of a challenge here is that them being so mobile also means they're more easily stolen by someone.
And you have a lot of different data on here. You have all your messages from your messaging systems, you have your accounts for those social networks, you might have accounts for financial information, and you might have even enterprised apps that you're actually responsible for protecting your company's information. So this has become very, very important, being able to protect this data, especially in a mobile environment.
So what we introduced last year on iPhone 3GS was all the data was encrypted in place. Now, we actually added special hardware to these devices that would have no performance impact. Basically, it's you know, hardware encryption engines in the hardware that would do it for no performance, no battery life impact whatsoever. Now, the big reason that we did this was we want a really fast experience of Remote Wiping.
So Remote Wipe is that you can send a signal to the phone as long as that phone is still online that it will erase all that customer's data. So you can do this from, you know, if the device is lost. And we wanted that to be very, very fast. And if you encrypt all the data, you can just throw away the keys, makes it very fast.
Now, it also has this concept of protecting the data at rest. Now, this is kind of a concept that evolved from desktops. And the idea on desktops is that a lot of desktops, you can image your data and move it to somewhere else to try to compromise, or someone can steal a hard drive out of it. Now, this doesn't really apply to a lot of these mobile devices. So it makes-- if you have that device, it makes that device still very vulnerable to a local attack.
Now, the other thing that we added last year was encrypted backups. And this means that the data is protected when it is off the device and being backed up to a host machine. So what we're introducing for iOS 4. We have this goal to keep the data safe even if the device is compromised. So what we did is we added the ability to tie the encrypted data to the user's passcode. So this means that it's actually something that the user knows themselves that unlocks that data, so that data is only available when the device is unlocked.
Now, we added API's in so you can choose data availability, whether it's only available when the device is unlocked, or it's available all the time. And we went about adopting this in iOS 4 in mail, which is by far, the most complicated app and does the most complicated background activity. And we're making those API's available for you to adopt in your apps, so you can tie into the same security mechanism.
And I want to emphasize here again, there's absolutely no performance impact to this because we're doing this all in the hardware engine itself, and it's all just streamlining with how the data reads and writes out of the hardware. Now, I also want to mention that we still had to enable encrypted backups, and we actually had retool all of our infrastructure to do this.
But we got one big benefit. We now can allow the key chain to be migrated between devices if they are in an encrypted backup. So this was kind the last kind of excuse not to use the Keychain is that your credentials wouldn't move from device to device when your users upgrade.
Well, now they do. In an encrypted back-up scheme, they just move right across. So passcodes, we are tying this to the passcodes. But I want to remind everyone that the passcode is only as good as you make the passcode. And passcodes can be pretty forced. So if you choose one, two, three, four as your passcode, it's not gonna be very strong. Someone is going to guess that.
So we put a bunch of mitigations in place. Now, the first mitigation that we've always had in place is that we have back off between failed attempts on using the UI to putting someone's passcode. So it's kind of incremental as you have failed attempts. But by the sixth failed attempt, it takes like, 10 minutes for the UI to come back up and offer to you to put your passcode here. So this makes, you know, someone who's stolen your device, if they are just trying to punch the numbers it makes it pretty difficult for them to guess. It takes them a long time.
Now, we've also had the ability to force complex passcodes on the device. We've had this for a while with configuration profiles. Now, what's new for iOS 4 is we actually give you a user-configurable setting in the settings-- on the settings tab to actually force the complex-- or to actually use a complex passcode. Also, we've had the ability to force and erase of all the user's data after a failed numbers of attempts at the passcode. This is also something in iOS 4 that we've made user-configurable in settings.
Now, another thing that we did in tying all the data to the passcode is we, not-- didn't just tie it to the passcode itself, we also tied it into a set of device keys in the hardware. And the reason that we did this is that it makes it-- it prevents people from taking the data off the device and trying to brute force passcodes there, since it's actually encrypted also with a key that's only available in the hardware. That means that you actually have to-- someone would actually have to do an attack on that hardware itself. And our hardware is fast, but it's not as fast as a botnet. So this actually limits the speed of an attack on these passcodes.
So I want to kind of just run through what technologies we put in iOS and kind of why we put them there over the generations of releases. So obviously, we have had, since the first iPhone, a passcode. And this was really, you know, at that time meant to prevent casual device access.
It was meant to stop someone, kind of, at the door and make them know one number before they could actually use that device. Now, even at that point in time, we had some Privilege Separation and Sandboxing. And what Privilege Separation is, it means that applications, either in the OS or third party applications, only have access to those services that they have privileges for.
And Sandboxing is that basically, they only have access to those documents or API's that they have privileges for. Now, this has kind of evolved over time because obviously, in the first release of iOS, there was no third party apps. And as we added third party apps, we added more Sandboxing, we put those apps in the Sandbox.
Now, for iOS 2, we also added Code Signing. And the reason that we did this is that now, the user knows that-- they know that there is known origins for every piece of code on their device. This makes it much more difficult to spread around viruses and the like because you can actually trace it back to whether it's an enterprise, inhouse app, or whether it's an app from the App Store, or whether it's code from Apple. We also added Remote Wipe at that time. Now this would, you know, like I said before, erases all the data in the phone, if that phone is still online, you can send it a signal.
And obviously, at that time, what has to happen is we actually had to overwrite the data with zeros essentially, to erase that data. And then actually, it was a pretty long process, especially for the larger storage devices. So last year, we added encrypted storage. The main reason for that is to make Remote Wipe very, very fast, and we added encrypted backups, which protects the data off the device.
And now, we're adding data protection. And this really means that even if a device is compromised in some way, it's stolen and it's a compromised device, that user's data is still protected because it's protected with something that only that user knows. So you can see where this is all going here.
We want all the apps to adopt data protection, both throughout the OS and throughout all of your apps. So we start it with Mail which is the most complex app, and we want you to go through your app and choose how your data is protected. Now, the big thing here is that for app surges in the foreground, when the device is locked and not doing anything, it's pretty easy to choose they want their data protected by the passcode. If you are doing some kind of multitasking app that has some kind of background task, you have to be a little bit more careful with your data, and you have to choose a few different classes to figure out how to do that.
But we want you to start adopting these API's and these concepts into your apps because our real ultimate goal here is that when the user puts on their passcode, they know all their data is protected no matter what. So I'd like to invite up Mitch Adler, one of our Security Architects, to talk a little bit about-- more about the mechanism behind us.
[ Applause ]
[Mitch Adler]
Thanks, John. As John said, I'm going to take you on a little deeper dive into the mechanisms we put together in our system to help protect the user's data with their passcode. It-- the goal, as John said, is that when the device is locked, the user should be able to be confident that their device is protected.
And in iOS 3, we were relatively confident that if I-- my device is locked and I hand it to somebody and I watch them not penetrate the defense of the device, they're not going to be able to get through my passcode very easily because we limit the tries and all of the mitigations that John talked about. But for iOS 4, we want to provide a mechanism that the user can be confident that even if they've lost their device, if their passcode, if their device is locked, that their data is actually protected with their passcode, the strength to their passcode.
That requires that we actually encrypt their data with some derivation of their passcode. And this is very useful, but we run into a problem. And that problem is that applications want to use some of that data sometimes when the device is locked. So we needed to provide a mechanism for applications to specify jar system how they want given data protected. That mechanism is data protection classes. There are three data protection classes that we have established in our system in our API. The first class is available and unlocked. That's the most protecting class.
The availability and the protection are kind of reverse of each other, when something is available to the system than an attacker who manages to get through our outer protections and get inside the system can masquerade as an application and access that data. So if you set your data be able-- if you set your protection class to one that to-- WhenUnlocked, we'll protect the data cryptographically when the system is locked, and we'll make it available to your app when it's unlocked.
The second class is available after fist unlock. This is the kind of compromise class. We noted that many of the attacks on the device that compromise devices and get access to running code on the device requires the device reboot. In the process of rebooting, we can reset things that have been exposed.
So we add the second class, so that if there is data that you need to continue accessing while the device is locked, for example, credentials to reconnect to your server because you've changed networks and now you need to reconnect and revalidate, you can protect those credentials better than not at all, but still have them available when the device locks and unlocks, because after the first unlock, it will be available for you. And then if somebody attacks the device and then forces it to reboot, we'll reprotect that data.
The last availability class is what we've had traditionally on all of our storage up to this date, which is it's available always. It is no less protected than it has been in the past, but it doesn't gain anything from data protection. But it's a way to express that need, if I need my data to be exactly the same as it is. So the two major clients of these classes that present them to you in the file system, which presents availability for WhenUnlock called ProtectionComplete and that available always called ProtectionNone, under the Keychain which provides availability for all three, WhenUnlocked, AfterFirstUnlock, and Always.
So these two clients, there is some risk that if the two clients were sharing all of their keys and classes, that if I were a client of one of the systems, I could use it to attack data stored in the other system. So for that reason, we make these very much independent. They have very intentionally similar semantics.
So when you're thinking about how you store your data, you can think about the problem the same way for the two systems. But from the point of view of how the data is protected, we use completely separate class keys to represent those classes, so we can isolate-- the people can access the Keychain from the people who are allowed to access the data on the file system.
I'm going to run through a quick example to demonstrate how we take some data that the user has and protect it through our new design system in iOS 4. So here's an example of a file, a mail that I happen to compose on the device, and it needs to be protected.
In iOS 4, every file in the file system or how it's made is protected with a file key. This is slightly different than it was in iOS 3 and that the whole file system is protected by a key. But in iOS 4, there's a randomly generated new key for every file that gets created.
That file key is stored in the files metadata. That file key is, in turn, protected by a class key. This is a class-- a key that was randomly generated at the time the class was established, and it protects the file key. If you don't have the class key, can't see the file key. If you don't have the file key, you can't see the contents of the file. Each class key is protected by an appropriate set of keys in the system depending on its semantics.
In this particular case, this is a-- protected with the user pin key, it's protected by two keys, the device key, to make attacks off the device less practical, and the user passcode key which is the tie that ties the protection of the file back to the passcode. The file is protected by the file key, the file key is protected by the class key, the class key is protected by the user passcode key.
There's one more thing that we needed to support in this architecture, and that was the ability to do fast Remote Wipe. In the past we have thrown away the one master file system key and it erased-- cryptographically erased the entire file system. Now that we don't have exactly one master key, we had to build one back in, and that's on all the metadata. The file metadata has file system key, that key, when erased, makes it cryptographically impossible to view the data on the file.
So to take this particular example, and show you how we take a collection of data and protect it, for an entire file system, we can have one file, like we just showed you, protected, the file protected by it's file key, the file key protected by it's class key, and the class key protected appropriately by a device key in our user passcode key. But since we've gone through this class key, we can have as many files as we'd like protected in this class.
So there's no limit, the class-- the-- each file can specify it belongs to this class. We also don't have to limit ourselves to how many classes we want. We can have a second class with exactly the same protections and maybe some different semantics on how you get the class key, and we can store it on the same data storage, same file system. We can have a third class with different semantics. In this particular example, this would be accessed always.
There's no protection that extends from the user passcode key to this class key. So this is how we store on our system things that are always available that are protected by the device key, but they're not protected by the user passcode key. The collection of classes that protect data on the system, we call a keybag.
The-- that collection of class keys is an important structure in our architecture. It's what embodies locking, unlocking, and protection states. There are three kinds of keybags we operate in our system with. There's the System Keybag, there's a Backup Keybag, and there's an Escrow Keybag. The first two are relatively important for everybody to understand. The last one is an interesting detail for anybody who wants to do security analysis on their device.
System keybags, these are the ones you'd imagine, as I've just described, they're sitting on the system, they're protecting your system. They hold the class keys for all the data that's on your system. They have one tweak they do. They force all of the class keys, and then to be protected with the device key that makes it hard to attack this keybag off the device.
They're stored on the system. They're actually stored on the file system, which is interesting, because the fact that they're stored in the file system means that if you use a weak passcode that's trying to protect this keybag, and we leave that data on the file system, somebody later can come and find it even if we've moved on to a new keybag and use that old keybag to try and steal your class keys. Because when passcodes change, we don't change the class keys. That way, we don't have to scour the entire file system trying to update it for this metadata.
So in order to mitigate that attack, we actually protect the storage of the keybag on the file system with a key that we can erase. Every time the user changes the passcode, we destroy the old key, we write a new copy of the Keychain out of the keybag out, and we write a new-- we use a new key, and we randomly generate a key.
So we've cryptographically erased the old keybag so that it's older, maybe weaker, passcode protection is not exposing my device anymore. The system keybag is also responsible for managing the lock and unlock state of the system. When the user enters their passcode, the system keybag is asked to expose the class keys that should be exposed when the device unlocked, and when it's told the device is locking, it discards those keys, forgets those class keys.
So it's-- this is the center of the universe of the device locking and unlocking and protecting the user's data. But in order for us to maintain our encrypted backups and to maintain our protection through it, we also created backup keybags. Backup keybags are created new for every back up. Their class keys are generated randomly and are different for every backup you've-you storeon your host.
This holds the class keys that protects the data while it sits in the backup on those machine. These class keys, instead of being protected by the pin, are protected by the backup password. So when you have a protected backup, we-- everyone who would have used the pin on the device are going to be using the backup password in the protected backup keybag.
We happened to use PBKDF2, for those who care to generate the key. I don't remember the number of iterations off top of my head, happy to look it up for you if you want to know. If you don't choose to have a backup password though, we do one thing to protect credentials that are on the Keychain.
If you don't choose to protect your backup, we protect some of the Keychain class keys with the device key, and not the backup password key, causing them not to be able to migrate, and we'll get into that in more detail later in Adoption. The last kind of keybag is a keybag we created to enhance user experience. It was created for systems to be able to hold on to. It's called the Escrow Keybag. It was created for other systems to hold on to improve user experience.
The downside is that the improved user experience we want is systems that sync with your device, can sync without you having to enter the passcode on your device. And right there conceptually, is a security issue, in that now there is data in the world that can unlock my device. So we did a few things to mitigate it. First, we considered that the system that you're storing the Escrow Keybag on is a system you're already syncing you data to.
So if somebody can compromise that system and get your Escrow Keybag, additionally being able to compromise your device, if they can get their hands on your device, is not a big leap in security weakness. It's a little-- it's irritating and annoying but it's not of great loss, because most likely, all of your sync data is sitting on that host that was compromised. Them getting your Escrow Keybag is a potential future problem, but immediately, they've probably already taken all of your data.
The other thing we do is that we keep a key on the original device so we can invalidate the Escrow Keybag. It's part of the protection. The class keys in this keybag are protected with a device key, so this keybag can't be brute force except with access to the device, and the key we generated when we made the Escrow Keybag and stored on the device.
So if we could throw that key away on the device, we can make that Escrow Keybag cryptographically incapable of reading the data on the device. So anytime we decide that somebody's not worthy of trust, we can throw away the key, of course, part of the Escrow Keybag, and they can't access our data anymore.
Something I didn't mention is the Escrow Keybag does contain actual copies of the master class keys for the devices classes, which is why it can unlock the device without the user's passcode. So to dive a little deeper into the filesystem protection, all of the filesystem data is encrypted. Everything on the filesystem. It has been since iOS 3.
We've changed how we encrypt out the data on the filesystem. The metadata uses the filesystem key as I showed you in the diagram. That's what destroyed on Remote Wipe and breaks the chain of cryptographic exposure, so we-- your data is not exposed. The files are encrypted to an individual file key which is stored in the metadata.
The default, when you're creating a new file in iOS 4, is ProtectionNone. This is mostly for compatibility with applications, we don't want you to break all the applications that do anything across lock. We want them to opt in and decide what they-- how they want to protect it. And again, a reminder, there's no performance impact. We are already encrypting and decrypting. We've just changed what keys we're using in the process of pushing stuff back and forth to the file system.
The Keychain-- it's also protected by classes just for the Keychain, as the concept of migratable and not migratable. That as-- that actually doubles the number of classes that are available for the Keychain because you can put a piece of data into any of the three classes, and either migratable or not migratable. The default on the Keychain will remove data from back to a device by iOS 4, or if you create data without adopting data protection, will be always as migratable.
The three new classes that aren't migratable have the suffix ThisDeviceOnly. So WhenUnlock, ThisDeviceOnly, WhenUnlock-- AfterFirstUnlock, ThisDeviceOnly, AlwaysThisDeviceOnly. So this is a change that is in significance to people who want to protect data and don't want it to move form device to device, because our default now is going to allow things to migrate through a protected backup. We thought that was the right compromise for user experience. But if you have data that is really not supposed to migrate off of this device ever, you'll need to update your use to annotate that data and say it's not supposed to migrate.
Handling of the passcode. So one of the most critical things in trying to keep the user secret a secret is how we handle the passcode, because we have given that secret, and we have it for a while, and we really don't want to keep it because it's the user secret. It's not our secret. So we do two things to try and help protect that user secret.
The first thing we do is try and make it difficult to brute force attack the key that we derive from the passcode to avoid simple brute forcing the-- a user's passcode. And as John mentioned, we take a hardware key, something that's actually embedded in hardware individual to a given device, we do a derivation with that hardware key which resembles PBKDF2, but isn't exactly, and do a bunch of iterations to make you need to use that device in order to be able to attack the passcode.
This means that an attacker whose managed to get access to your device, broken through our outer defenses, gotten to the point where he's got a copy of your system keybag and wants to try to unlock it, and knows what it should look like-- what the header it should look like if it's unlocked, actually has to keep trying on that device to unlock that keybag. This helps us be able to control the time it takes to attack once. For example on an iPhone 4, on a new hardware, we use 50,000 hardware operations to drive the key from the original passcode. It takes about 50 milliseconds, give or take.
And if you do the math from there, for a reasonable passcode somebody's put on the device, it starts taking significant amounts of time, cryptographically interesting amounts in time, for you to brute force somebody's passcode. The other thing we do is we handle the passcode and the passcode key very carefully.
When we've given the passcode, and we to return it into a passcode key, we're careful to erase remnants to make sure that the user secrets stays the user secret. The thing we retain when the device unlocks, are the exposed class keys. So when we move from state to state, class keys come and go, and they're available and they're not.
Example of this, a device boot, we start out-- we don't know the user's passcode, he's never entered it, we're fresh and clean. The only class that is available is the always class, ProtectionNone, AlwaysThisDeviceOnly are available, the first two protection classes aren't available yet because we don't-- we haven't been able to unwrap the class keys. When the user enters their passcode, we unwrap the class keys, we-- if we get their passcode and their passcode key that help protect the class keys, but we keep this class keys around. So now, all of the classes are available.
WhenUnlock, AfterFirstUnlock, they're all available, the device operates, people do their normal operations. But at some point, the device gets locked, either by idling to lock or by the user clicking the lock button and wanting the device to lock itself. When that happens we forget the class keys for the first class. So that things that are only available when unlocked are no longer available, the device is locked. Note that the second class stays around as is defined after FirstUnlock, it remains available until we reboot, then we'll get back into the initial state, we've lost all the class keys.
So in summary about our mechanism and how we put this all together, our protection extends through a keybag, it comes from the user's secrets and device keys to bind it to the device and bind it to the user, it goes to the filesystem in the Keychain and the data stored in those places. The passcode key derivation has been made resistant to brute force attack to help protect the user's passcode. And the Keychain contents have been made migratable when we have protected backups. And with that, I'll hand it back to John to talk some more about configuration.
[John Wright]
Thanks, Mitch.
[ Applause ]
. So for user-enabled data protection, actually on an iPhone 4, it's extremely simple. The formats already there in the device. All they have to do is set a passcode, and data protection is enabled. Now, on our last generation of devices, including iPhone 3GS and the iPod touch, the 3rd generation iPod touch, it's a little bit more complicated and that we don't have the right file system format on those devices, and you have to upgrade the file system format. And the way we do that is with an Erase Install.
And so, the user has to backup their device, do a full Erase Install, and then restore from that backup. And of course, the iPad is also capable of doing this, and it will inherit this feature with iOS 4, and it will also require an Erase Install to get that feature.
Now, to check to see if Data Protection is enabled if you go to Settings-> General-> Passcode Lock, and there is a picture right there, if you look at that little string at the very bottom of that screen, it basically says Data Protection is enabled. So now, you know you have it on that device. Now, I want to point out a couple of other things on this screen.
So I told you before that users now can configure their device to be able to Wipe if-- on 10 failed passcode events. That is that setting right there. And they're also able to set a arbitrary complex passcode by turning off the simple passcode, and then the dialog that comes up to change their passcode is a full alpha numeric keyboard, and they can choose what size length complexity they want.
Now, for devices that are being managed and our system to manage these devices is-- our Configuration Profiles. You can set this Configuration Profiles to enforce certain security requirements, and I'd like to point a few of those out there. So, the first one is that you can require data protection to be enabled on that device.
You can also require a passcode be set, the link of that passcode, and the complexity of that passcode. You can also require a minimum passcode grace period, and the grace period is how long a user has from the time they turn off the screen to when they turn on the screen again that it requires a passcode.
And you can also inquire that all the backups from that device are encrypted backups. Now, something else that we're introducing with iOS 4 is a way to manage your mobile devices, a bunch of API's actually use these Configuration Profiles with third party servers and third party device management systems. And these device management systems will be capable of doing initial device configuration and automatic updates of these Configuration Profiles, and then also be able to implement their own Remote Wipe capabilities.
And there was a whole session on Tuesday that went over how these API's work. And we've assumed that third parties will be adopting these into their device management systems. So that really makes a very capable management system for you guys to be able to implement these security type-- or these security requirements as well.
So the whole idea here is that we want configurations to be dead-simple for any users. We really don't want them to think about it other than they set their passcode. And we want these security requirements to be fully manageable by enterprises. And that's really the whole configuration story there. So I'm going to turn it over to Mitch to talk a little bit about adoption of these API's in your apps
[Mitch Adler]
So I'm going to talk a bit about how you adopt Data Protection in your application. To go back to what John was talking about a little bit, we really want to protect your customer's data, we want to protect all of our mutual customer's data, we want you to assume the data needs protection. You don't actually know what data users are going to decide to put inside your app. If you're making a note-taking app, they might put their credit card number in your app. It doesn't seem like a good idea to me, but they might do it.
We need you to help put the data into the right class. Since we don't automatically try and protect all your data to preserve functionality of your application, we need help from you to know how you want that data protected, so that we can do the best protection we can for the user.
We recommend you find the most protected class, and we'll get it to how you decide on what's the most protective class you can. It's here. We also want you to help put the user data back into places that's protected because the file system and the Keychain are protected by Data Protection. RAM, you have your user's information and it's not protected by Data Protection. So somebody can attack the device and get into your process, which is not an easy feat.
But if they can do it, they can steal data that's in RAM. So we recommend that you push the data out of RAM, push it into the protected containers when the device locks. So one of the first things you're going to have to do when you're going to adopt is analyze your data to figure out what you need to protect. You pretty much need to answer these four questions, and you can figure out what class and what location and how you want to protect that data.
The questions are what data of the users do I have, do I need it when it's locked, you know, does it belong in the Keychain, should it move from device to device, and we'll get in to each one of these. So how do I answer what data of the users do I have. Well, it's everything they create.
It's all the data users are entering, and it's the credentials that they enter to connect to things, and it's credentials you create on their behalf, if you make a connection and then wanted to create credentials to make a persisting connection, or reestablishable connection, those credentials are data of the users because it represents them.
Do I need that data when the device is locked? Well, for most app writers, the answer is no. If the device locks, your app doesn't do much, it's waiting for the user to come back and interact with it. So you don't. But some background-aware applications are going to need things like credentials, and they're going to want to put those credentials in such a way that they get protected, but they're still accessible.
Which is why we have the compromise of AccessibleAfterFirstUnlock, which is a good place to put things like credentials you want to use and be able to reuse as users move around their networks but want to get some protection from the classical kinds of compromises, which involve a reboot.
Then you have to ask does it belong on the Keychain. This is a question we've talking about for a very long time. Credentials belong on the Keychain, particularly, things that you want to migrate around. Things like passwords, keys, identities you've establish for the user or imported for the user. Large bulk data doesn't really belong on the Keychain itself.
Should it move from device to device? Well, the simple answer is yes. The user wants their stuff to move from device to device. But the more complex answer is, well, unless you have some compelling reason then it doesn't, and you'll-- you in this room will probably aware of why you would want that to be the case.
We have an example on our system when you import VPN configuration profile, and you set up a VPN identity, that's the identity of the device, not of the user. So those identities stay on the device. They are not permitted to migrate from device to device. But we have to make our system aware of the fact that those might go away if I restore a backup. I'll get half the data back, but I won't get the migrated VPN identity, and I'll have to deal with that state.
So if you don't have a compelling reason to make it non-migratable, make your data migratable. So we'll go through a few examples to help clarify this. The first example I have is a theoretical game. I have a game that has some online play, it has some credentials it stores. It has some saved games it stores.
That's pretty much all the data we have from the user. So for each one of these, I've gone through the questions. Do I need access to the credentials when the device is locked? Well, no, my game has stopped and the device is locked. I don't need to connect to my server. It's-- we're done at that point.
Do I need it to migrate? Well, it's credentials and the user would like to be able to reconnect to our server if they migrate to a new piece of hardware. So, yeah, I'd like it to migrate. Does it belong in the Keychain? It's a credential. It belongs on the Keychain. So I'm going to put it on the Keychain and I'm going to give it the attribute AccessibleWhenUnlocked, the best protection I can.
I also have saved games which have similar attributes. Yes I-- actually, no, I do not need access to them when they're locked, yes, I want them to migrate, but, no, they don't belong on the Keychain. So the protection class I give them is ProtectionComplete, and I use their location on the file system to control their migration. I put them in my documents folder in my app, and those automatically get me moved into my backup and moved back to my app, and they're accessible when I won't migrate from device to device.
Second example is an online service. So suppose I have an online service that has decided to participate in a new background task completion multitasking type, and it has some credentials, it has some data that is trying to push up to the server in the background, or it's trying to not burden the user with failing to push my photo up to the server, and it has some cash data it wants to display because it's got some stuff it's pulled down from the server for fast access.
And all of these are user data. So start with the service credentials. I have some service credentials that I do need when it's locked because I'm participating in background task completion, and I might change networks and need to reconnect to actually complete the operation I'm doing with my server.
So next question is do I want to migrate this data? Well, it's credentials, they belong to a user, I'm-- I pretty much want it to migrate so my service will work on the new device it get to right out the box. And does it belong in the Keychain? Well, yes, it's a credential. It belongs in the Keychain. So the protection I give it is AccessibleAfterFirstUnlocked.
This is the second category of protection. It's not quite as good, as AlwaysIsProtectedWhenUnlocked, but it does give us some protection against the task that require a reboot. So we choose the second best protection because we want the user experience to be good. The second class of data we have is a data that's being uploaded. So I have some data the users put in the background.
Do I want this access to the data when it's locked? Yes. Do I want this data to migrate? No, this is an in-process operation. This data's going to go up to the server. I don't need this data to move. Does it belong on the Keychain? No it doesn't belong on the Keychain. It's bulk data, it's a big file.
So I have to put it on the file system, and I've put in ProtectionNone. We have to admit we did not provide file system API's to get to the second class. We didn't think they were as valuable as they might be, and if you find reasons why they are interesting to you, we'd love to hear them. This is a case where it might be interesting, but in this case, we choose ProtectionNone and we put the file in a place it doesn't migrate, which would be the cache's directory in your application, for example.
Cash data, on the other hand, we don't need when the device is locked, because it's for-- presenting data to the user. And when the device is locked, we don't present anything to the user. We don't need this to migrate, it's caches. We might choose to. But in this case, we don't care to. Does not belong on the Keychain.
It's large data. So we put it in ProtectionComplete which protects it when the device is locked, and we put in it our caches directory so it doesn't migrate. The final example is a relative simple example if I make a diary. It's a place somebody can record their thoughts, whatever they want to put in there, their credit numbers because they are crazy.
So I have this diary which is on the device, and we don't need it when it's locked because it's for the user. We do want it to migrate, and we don't want another Keychain because its large unknown pictures, whatever they use or want to enter. But we do want to protect it. So we put it in ProtectionComplete.
This allows it to be protected with Data Protection, and we put it in our documents folder for our app, probably the simplest example of all. So once you've made your protection choices, and you've put your data into an appropriate class, there is one more thing that you want to do when you adopt, particularly, if you are an app that's running on the background or running while the systems is locked.
Your app does not really care with the systems is locked, and just pretty much left this data on the file system and tries to quit if the system locks, you'd-- there's not a lot you have to do here. But if you are a background app, or want to operate while the system is heading towards lock, there are some stuff you need to do.
There is a notification that comes through. There is actually a symmetric one for this also, that says protection data will become unavailable. This is a symmetric one that says become available, but it's less interesting. It's just telling you, you get your data back, and then you can choose to access your data at that point. This one is relatively important because it does give you a moment in which you can help enforce the security of the users' data.
In response to this notification, we ask that you purge the data in memory that is not necessarily-- that is not necessary when the device is locked. Specifically, we want you to take the data that needs protection, put it back into the containers that it's supposed to be protected in, and close those containers. So you push it back in the file system, you push it back on the Keychain, you get it out of your local address base, so that if somebody is clever enough to grovel your memory, they won't get that data either.
In order to make our system actually have a predictable behavior about locking, we have to give an upper bound to how long an application can hold us off from causing the system to actually lock. So you actually have-- only have 10 seconds to complete this notification. If you don't complete this operation in 10 seconds, we're going to lock the device behind you.
The reason why that is interesting is once the device is locked, you don't get access to the data that's in the highest protection class. You will actually get errors trying to reach in the files to get EPERM errors saying, no, can't read that data. We want you to be resilient to those kinds of failures, not necessarily your app has to keep chugging along and doing great, but don't crash, don't do spectacularly bad things for the user, considering that that might happen.
To move on to some interfaces in the file system. So how do I create and set this attributes. I need to help the system know. There are two API's we've added to help you communicate to the file system, what protection class, you want your data in. The first is in NSData writeToFile, there are new options added.
The file that is created will get the ProtectionComplete or ProtectionNone, depending on the option you include. The second is NSFileManager, has an API to set an attribute of the file, which is the protection key, which will then set the class of the file, the protection class of the file. You can use this on any existing file on the file system.
It's sticky. And then once you set the class for the file, it retains that class in the file, you don't have to tell us again. And most importantly, you can use any other file system access you want to, and then it will operate normally, except for the fact that if the device locks, and it's in a locked class, we'll get errors when trying to access it. So if you are creating a file to hand off to another subsystem on your device, you can set its class before you hand it off. If you know you've requested a file you created by some other system, you can find it, set its class.
The other thing we need to point out is that your existing files that have been run long, your documents and your documents folder are not going to have any protection classes except ProtectionAlways. So if you want to protect that data for the user, which we hope you do, you need to actually find those documents and set the protection class on the files in those documents.
So choosing your protection on the file system, this actually will be simple. Use ProtectionComplete, you know, protect the user's data. Right up until you find a good reason that you can't protect their data. You need to use it when you are in the background, this is probably the most popular.
I really can't think of many other reasons why you wouldn't want to protect the user's data, although you might come up with some. The Keychain has new interfaces, now just new attributes on its existing interfaces. SecItemAdd and SecItemUpdate have always taken a query with the dictionary of parameters in it. There's a new attribute case like accessibility.
You can give it one of these values, and that will set the accessibility of your Keychain item. Just like the file system, the Keychain needs update if you want to change the accessibility class of a given Keychain item. By default, when we move the Keychain back to the device it came from because all backups that are currently out in the world, can only move back to the same device, all the Keychains out there will go back to the same device. But when it returns to that device, we set all the data to AccessibleAlways, which you should note is migratable.
So if you really, don't want it to be migratable, you should hit it with the hammer and tell it not to migrate. If you think it should be less protected because you want to operate in the background now, your app's updating and wants to upgrade in the background. You may want to set its protection class to be type to, AccessibleAfterFirstUnlock. If you don't need the data at all, except when you are running unlocked, set it to AccessibleWhenUnlocked.
So summarize that basic decision tree, the other direction. When you have data and you are trying to consider on the Keychain, how am I going to protect this data? You should start with the most restrictive, but we recommend migratable, which is AccessibleWhenUnlocked. That's probably the right class for the vast majority of the data that is on the Keychain.
But if you find reasons that you need to access a credential when it's locked, the most obvious one I thought of is I need to get back to that server because I was just told the network changed and I still have stuff to talk to that server about. Use AccessibleAfterFirstUnlock, that still maintains some protection for the user's data, but let's you do the background operation.
And if you really create data for this device only, and really, if you create device-- for this device only, be sure it's for this device only. And then you can make the user experience with that data appropriate, and make it for this device only. But if you suddenly discover that that data was for the user, when they go to a new device, they won't get it. So we recommended you think seriously if you want it to stay on this device. But you will know. I mean, if you create a data that's for the device and not for the user, that will be relatively obvious too.
So a quick example of modifying the access a SecItemAdd, those of you who are using the Keychain already will recognize this. You build the query, you called SecItemAdd with that query as data to the Keychain. All you have to do is add one more set of attributes you put in the query dictionary, kSecAttrAccessible, in this case, accessible and unlocked is the-- actually what we're requesting. And then you can use that SecItemAdd. You can also use the SecItemUpdate.
So some way in our adoption, it's relatively straightforward. We're asking you to protect your users' data, we're asking you to choose the strongest protection class you can, and we're asking you to update the existing data protection on the file system and on Keychain. We're also asking that you use the Keychain. It supports migration now.
That was a big hindrance before. If people would put on the Keychain, they're-- you'd migrate to a new device, your passwords would all be lost. It was really irritating for users. That's gone now. So we think we have all the reasons or mood to now use the Keychain.
So what we talked about today, John started talking about why we want to help protect the user's data. These devices are all more mobile, they're much more active, they actively do access in the background. The data on these devices are more personal, and there's a lot more of it.
So it has higher value, particularly to an appointed attack, and it looks and says, hey, I want Mitch's data, I'm going to steal his phone, and get his data off of it. And we're willing to help deal with this, we want to tie the data to a user's secret. That way, the user owns the secret, not us and not our system, not penetrating the owner's system. The data protection model is to protect the data with the passcode.
So all the user data is supposed to protected with a passcode to strengthen against devices that get compromised. So if somebody takes my device, they can break through the front barriers that we think are pretty strong, but are not perfect, if they get through that, they still have to get through the cryptographic protection with the user's passcode.
We also protect the user passcode by tying its derivation to a key to the hardware, so that brute force on that passcode, even if I have all the data inside the device, if I've gotten into the device, requires I do operations on the device to attack it. I can't send it out to my botnet and get a factor of a million on my attacks speed. We want data protection to always be on. It is always on when the user set his passcode. You can't have it off. You got a new passcode, data protection comes on.
And to reiterate again, there is no performance impact. We're already encrypting and decrypting data as it goes to and from the file system, and to and from the Keychain. All we've done in this update is change the architecture of what keys we use when we push the data in and out of the storage systems.
And lastly, we talked about was how you guys adopt and help us make all the user's data protected. We're asking that all applications protect the user's data. Since user information is all over the place, any application where I can have a text deal and enter data, I could put something that I want protected. We're adopting it. We're adopting it as quickly as we can. We chose mail first since it was one of our most complicated ones to prove out that the technology worked. We're definitely going to be adding more apps.
We're asking you to put your data into appropriate classes, to update your existing data into the appropriate classes, and we really are trying to encourage you to use the Keychain. We think there are no excuses left to not use the Keychain for credentials. So if you are interested in any more information about the presentation, you can contact our Evangelist or you can check out the forms. There are few related sessions. The first ones of the Multitasking on iPhone have already occurred, but there is rerun of them tomorrow morning.
And, if you want to pay attention to how you handle being a multitasking app, because those moments will be interesting for you to decide about data protection. The Managing Mobile Devices session was last Tuesday. You can catch the replay when they are posted. It talks about how to configure devices and manage them remotely.