Some background: one of the apps I worked on makes use of HCE (Host Card Emulation) - when the device is close to the custom hardware, the implementation of HostApduService is created and started by the system. Upon its start, it reads some info from SharedPreferences and handles the communication with the custom hardware accordingly. So far, so good.
At some point I noticed the strange crashes gathering in Google Play Vitals - as it turns out, since Android 8.1 ContextImpl
checks the if the user has already authorized or not before attempting to read the shared preferences; if not, the Exception is thrown. This is how I learned about Direct Boot implications.
The documentation on Direct Boot mode mentions that the Credential Storage encryption prohibits anybody from accessing the data until the user has provided some authorization. I can not point to exact place in the documentation atm, but I am pretty sure that once the device was [re]booted and the user has entered authentication data, anything stored in the Credential Storage area (including, but not limited to the SharedPreferences) should become available for read/write.
But, some of the app's users claim that sometimes the device-hardware communication does not work even if they weren't rebooting the device for pretty long time. And the only way to cope with that is to autenticate the device - enter the pin code, touch the fingerprint scanner, etc.
So this got me wondering - how does this part of encryption work and is it possible that some vendors change this feature's implementation so that sometimes it kicks in after the device being in the locked state for, say, one hour or so? I can understand the need to turn the device's screen on so that NFC starts working - documentation on NFC mentions that NFC is put to sleep when the screen is off, for the security reasons. But why would that require the device to be unlocked? Or it's not about vendors per se, and my understanding is just plain wrong?
Upd. I have a broadcast receiver which wakes the app up once the device reboots - I need to do some work here, and the part of that work includes reading data from SharedPreferences
. After I changed the action filters of that broadcast receiver so that it's started after the user has actually authorized herself/himself, the vast majority of crashes related to the attempts to read the content of SharedPreferences
while being in the encrypted state is gone, but a very small amount of them (like 0.1% of the previous amount of those crashes) is still here.
At that point I'm pretty convinced that it has to be connected to the device jumping back to the encrypted state, but
- I am not sure how to cope with that without falling back to 2. and
- I don't want to move the data required for the communication with the custom hardware into the Device encrypted storage.
Are there any ideas of what could be the underlying cause and how one could deal with that?
Upd. 2:
Direct Boot Mode documentation now contains the following statement:
Credential encrypted storage is only available after the user has successfully unlocked the device, up until when the user restarts the device again. If the user enables the lock screen after unlocking the device, this doesn't lock credential encrypted storage.
So basically the phone should not hop into the encrypted state after the screen lock, it should only be happening after the reboot and before the authorization.