RFC: Revision of /home encryption on SFOS

I would like to revise how data is encrypted on SFOS and design an approach that would protect our data better. The description below is my understanding of the state and suggesting solutions to the problem. I am giving some background as well, something I’ve learned recently and probably few of us are on the same boat as me. It is mainly targeting fellow developers and consider this as RFC. As it is about data safety, it would be great o get the more eyes looking through it.

Current state

While I do not have any official device and cannot confirm it myself, here is the information from fellow users as far as I understand it. On the devices with encryption of home partition, we use LUKS with the PIN entered by user to encrypt the data. Cryptsetup/LUKS would protect your password/PIN by stretching it through number of iterations. Usually, number of iterations is found by doing them for some period of time, 2s for example. However, assuming that mobile phone CPU is weak, we get rather small number of iterations performed. With the attacker having ability to load and boot any image on our devices (open bootloader), we can expect that LUKS header and data is easy to extract. As PINs are short, number of combinations is small and, when attack is done on PC with more powerful CPU, we can expect that the brute force attack is fast in unencrypting the data.

In other words, data can be considered as not encrypted for most of the cases.

Aim

Aim is to design an approach that would allow us to enter relatively short password (6 chars,numbers,symbols) and have data encrypted with the high entropy key.

Example with TPM

On PC, equipped with TPM, it is rather trivial to secure encryption keys. You could either generate them on TPM or just store them on TPM. By adding access protection with the password, even short one, makes it very difficult to access the key due to the lockout mechanism in TPM. Namely, after a number of tries, 10 or more, you would not be able to try again during some defined period of time (1 hour, for example). As a result, brute force approach is rather inefficient and would protect your data from most of the attackers we could experience in practice.

SFOS has a similar profile to PC - as we cannot lock our bootloaders. So, probably similar approach is needed.

Encrypting data

On SFOS official devices and ports following them, LVM is used to manage partitions allowing us to encrypt /home partition using LUKS/cryptsetup. On unofficial ports based on LOS, it is still possible to encrypt data. Here, fscrypt can be used for devices with newer kernels. Alternative is to use loopback device for home data and encrypt with LUKS/cryptsetup.

FSCrypt and LUKS allow you to specify multiple passwords. As a result, we could use one “recovery” password and one hardware backed password. The latter will be used in practice while the former can be accessed when hardware keys are wiped or for other reasons.

In principle, data encryption protection boils down to protecting your keys. Below, two cases are considered.

Hybris ports with Android Keystore

Android Keystore provides the means to store keys in hardware backed stores. In practice, it is frequently realized via TEE of Qualcomm. On newer devices, we may get “secure element” (strongbox or similar) that would offload key storage to separate hardware.

Looking into Android Keystore API, I didn’t find any means to protect the key with PIN/password and having something similar to lockout used by TPM. Key usage limitations are are implemented via Android and are out of our usage case with the attacker having root access. Which means that we have to design the protection by tying it to hardware limitations. However, it can be assumed that the user with root access cannot obtain the key stored in the hardware but can just use it. The latter assumption means that we rely on Qualcomm to implement hardware based keystore according to its specs. Bugs in TEE could creep in, which users should be aware of.

I propose the following scheme for encryption / decryption.

EDIT 9 Aug 2021: For updated proposal, see RFC: Revision of /home encryption on SFOS - #23 by rinigus

Original proposal: For key generation and encryption:

  • create hardware backed AES256 private key using Android keystore, name it “HWkey”
  • create random key (32 bytes) used for LUKS encryption, name it “LUKSkey”
  • create salt and store in /etc
  • generate user password key using salt and user password. PBKDF2 or scrypt can be used for that user key generation, name key USERkey.
  • determine hardware performance in decrypting some smaller encrypted data blob encrypted earlier by HWkey. Should find how many times per second (N) can data be decrypted on device.
  • encrypt LUKSkey using HWkey at least K times (nested encryption) and, after that, encrypt using USERkey once. Store encrypted blob, K, and salt. Ensure that K is >= N

For opening LUKS container :

  • get user password from user’s input
  • generate user key from password and salt
  • decrypt encrypted blob once using userkey and K times using HWkey

Decryption would take time, depending on K selection, a second or more. The scheme ties decryption to used hardware and would limit brute force approaches to use the device for cracking user password. Depending on user password, fully random alphanumeric sequence of 5 symbols takes (26*2+10)**5/24/60/60/365 ~ 29 years to get through.

USB keys

Alternative to hybris would be to use external USB devices to keep LUKS encryption key. It can be combined with the user password, similar to hybris approach. I guess we can design approaches with plain USB key holding decryption key (hoping that phone gets stolen without USB key) or have some extra protection from USB devices designed to keep encryption keys. If USB device is made to support encryption through device only, approach similar to the one proposed for hybris can be used to limit brute force attacks. But that would probably require checking and taking into account available API/hw support.

Other approaches

Other ways of combining keys are possible, such as NFC smart cards, QR with a part of encryption key, for example. So, design of the applications responsible for encryption support should be flexible and allow us later to add plugins. Together with USB keys, these approaches are of special interest to native ports (PinePhone) where Android keystore is not available. Or to the users who would prefer it instead of Android Keystores.

Implementation

It seems that we will need to write:

  • an application that provides decryption key to LUKS or FSCrypt with the support for multiple key providers
  • an application handling user provided keys

Again, as I don’t have official device with encryption, I don’t know how flexible current solution is. I don’t even know whether currently used applications are open source. If we cannot use them, I suggest to write applications immediately using cross-platform approach that would allow it to be used on SFOS, Plasma Mobile, and maybe UbuntuTouch.

EDIT 9 Aug 2021: For updated proposal, see RFC: Revision of /home encryption on SFOS - #23 by rinigus

12 Likes

Just a note without having any idea on the technical side of things. I don’t think its a smart idea to rely on hybris/android tech/APIs. And yes now we use it (hybris, xperia etc) because we don’t “have” an alternative (yes yes i know pine etc) but that might not be that case in the future. We probably need a SFOS solution (whatever tech people decide what that would be).

1 Like

That’s correct, hence I looked into several options and suggested to make it via plugins. As LUKS and FSCrypt allow allow multiple passwords/protectors, even multiple key solutions can be used. However, at this point, solution based on Hybris/Android keystore could be the easiest to use for many of us.

  1. I don’t see why you use salt in /etc. There’s no point.
  2. Is there any good article about how hw keys are stored in TEE on Android?

1: Salt is one of the arguments to key stretching functions (as PBKDF2). /etc is as good place as any. LUKS stores its salt in the header, for example.

2: Good question - I have seen some descriptions of TEE and general principles, but I don’t know where it is in practice. Overview of the architecture is at Hardware-backed Keystore  |  Android Open Source Project . It probably depends on implementation of particular device/SOC. Some newer devices could have separate HW for key storage and encryption functions (StrongBox or similar).

From reading up on Sailfish Secrets, it looks like many goals align with it. One issue would be that SFOS Secrets are running under user session - so some kind of OS level secrets would be needed (separate user for keeping secrets for LUKS/FSCrypt encryption?). But otherwise, design with different plugins would fit quite nicely. Advantage in writing TEE plugin(s) would be their reuse in Secrets framework by other apps as well.

Would have to read up on Secrets API and see if there are any other aspects regarding its use for this purpose. Maybe someone who knows that API could give a feedback regarding it…

1 Like

So, the only reason for salt existence is that it is a required argument for PBKDF2?
Cause it adds no real security here, since /etc can be read in recovery.
So it’s no different than just using some fixed value for salt.

PS I’m actually more inclined for FDE, than just /home.

Also, regarding TEE, on phones with unlocked bootloader (all current SFOS phones) one can always boot a custom kernel with custom TEE extension. So TEE is not a panacea, unless the keys are stored in HW and TEEs have check-only access to them.

Re salt, take 2: As far as I understand, it is a good practice to generate unique salt for each use case. Probably not required here to be unique, but should be no harm done either. As for adding real security - i does not make brute force attack significantly harder on that step. However, I expect that it stretches user provided password into larger key space in a rather uniform manner and leads to a better key for encryption as used in this case. Take my response with a pinch of salt though, I am not an expert in the area.

Re TEE keys: TEE bugs exist and some exploits have been reported leading to stealing the keys as well. See https://bits-please.blogspot.com/2016/06/extracting-qualcomms-keymaster-keys.html . However, it is assumed that TEE stored keys are hardware backed, as far as I can see in Android docs. There are also devices with separate secure unit which is even better backed by hardware than TEE. Both use the same API in Android and we could design the plugin to store in the best available hardware. As for loading TEE extension to read out the keys, I have not found any recent example or description of that. Have you found any example / code that can do that? In generic or device specific manner?

Re FDE: While nice, it could be a step bit too far. On official devices and similar ports, /system and /vendor are together in root partition. So, if you encrypt that, there will be no access to large fraction of drivers. We can show some messages on screen, as done in recovery image, but I don’t know much about user interaction in this case. This is in contrast to /home encryption case where most of the stack is booted and available.

In general, I want to keep targets realistic and make significant improvement to the current state. So, even if there are vulnerabilities in TEE that NSA can use, it is still OK to protect data in the case of device theft and crimes associated with it. Aim is to raise a bar as much as we can while being able to deliver it in some reasonable time. After that, the approaches can be improved and developed further.

It’s excessive.

It’s not making it any harder at all.

I’m pretty sure any commonly used hash function does that on any input. That’s one of the properties (avalance effect) of hash functions.

PS We shouldn’t fall into this whole security theatre thing (hell, we already have non-existent “encryption” via numeric PIN in current SFOS), where we put some security buzz-words w/o analysis how it can and will be attacked.

@rinigus, as much I appreciate your pondering, I think you are looking too far ahead, because there no appropriate infrastructure exists for your ideas (at all).

  1. “I don’t know how flexible current solution is”
    It is just a GUI dialogue calling cryptsetup luksOpen with the entered passphrase (currently: PIN / numerical only).
  2. “Using a TEE, because there is no other user-accessible secure element (like a TPM).”
    But that would have to be a Free Software TEE, otherwise most people will not trust it. Do you trust Qualcomms binary BLOB TEE?
    See also: [idea] SFOS Support for Secure Elements (SE) (or Trusted Execution Environment (TEE)) - together.jolla.com
  3. “Using USB tokens, NFC tokens etc.”
    This is too inconvenient for the average user (i.e., almost no one will use that), and the basic infrastructure for using such crypto tokens is missing rsp. NFC does not work at all AFAIK.

IMO, first and foremost we should push Jolla to enable the use of alphanumeric LUKS passphrases, which has been suggested long ago and is a rather minor change. This would enable users who want to input “high entropy passphrases” to do that easily.
I also do not understand, why community ports of SFOS are not able to follow this simple scheme (you sound like that is not the case).

BTW, “For opening LUKS container: a. get user password from user’s input b. generate user key from password and salt” is exactly what Cryptsetup-LUKS does (with a volume specific salt), then using this “user key” for en- and decryption of the specific LUKS-volume. You just want to add another indirection with an additional key from a different source.

P.S.: As I once pointed out, I am convinced, that the enhancements you are aiming at are absolute overkill with the current state of security in SailfishOS and its infrastructure: There are so many outdated components in SailfishOS with known security flaws (e.g., the SFOS browser, Gnupg and many more). Plus it would be easy to get a malicious “really cool app” (e.g., “The Ultimate File Browser”) into the Jolla Store, because there are no checks in place, which would prevent that (Jolla’s Store guidelines prevent many good apps from getting in, but not that); there already is a Flashlight app which calls home on every use. And at Openrepos “anything goes” anyway.
As discussed, why should an attacker invest time into a scheme, which needs physical access to every device hacked and is time consuming, if one could easily employ remotely exploitable scheme affecting many devices (no matter which cryptography scheme is used)?
Thus Jolla better invests their time to alleviate the real, pressing security issues SFOS and its infrastructure have, instead of designing, implementing and deploying an overly complex crypto scheme.

P.P.S.: I am surely becoming bashed again for this by the tinfoil hats who want a “100% secure crypto scheme”, because they do not understand the gaping security holes elsewhere, plus that no crypto scheme is able to counter them.

9 Likes

I agree. Just using an alphanumeric password should already help a lot. A pin is trivial to brute-force, most alphanumeric passwords aren’t. The ability to use some hardware tokens may be interesting for some use cases, but they are more complicated and can introduce more issues than just changing what characters are used for the password.

@rinigus - thank you for bringing this important subject up!

Of course current solution is better than nothing, but SFOS does not have strong encryption. As I understand, then:

  • data is encrypted only if phone is switched off… but honestly, how often do we have it at that state
  • in decrypted state the protection of data in the phone boils down to other factors (what access methods are allowed, how we use the phone, etc)
  • current short numeric password is weak and @olf and others have suggested the easiest way to improve it
  • many users probably are not aware that when we do backup onto SD-card, then all important data is moved from the phones internal datastore to the one where by default no encryption is used (and there should be a clear notice about this in UI, incl suggestions what to do)
  • having easy UI to encrypt/decrypt SD card would improve things a lot
  • in the boot sequence the UI does not make very clear that one password is for decryption and the other one for login and that they can (and should) be different
  • there is a short text about SFOS security here Security - SailfishOS Documentation but actually I have not found end-user facing text in the context of “Security best practices for Sailfish OS”
1 Like

Doesn’t systemd cover some of those at least?

@olf, thank you for your thorough assessment. I will respond point by point below. In general, when proposing the solution I kept it to what I think is realistic and doable within reasonable timeframe (few weeks), at least in the first working form with TEE (or Secure Element, SE) support. As for infrastructure, most of the infrastructure is there (LVM and cryptsetup), just the rest needs rework.

But that would have to be a Free Software TEE, otherwise most people will not trust it. Do you trust Qualcomms binary BLOB TEE?

We are using the BLOBs anyway and I would trust it for this application. As for others, don’t know and can’t make choice for them.

USB/NFC tokes being inconvenient for the average user

When designing an approach, we just need to keep those options in mind. I am not planning to spend time on this, but it would be fine if someone interested in it could easily implement such solution. Risk perception is different for different users and implementation should be ideally flexible enough.

IMO, first and foremost we should push Jolla to enable the use of alphanumeric LUKS passphrases, which has been suggested long ago and is a rather minor change. This would enable users who want to input “high entropy passphrases” to do that easily.

Easiest way to push is to write new app that can be used instead. I haven’t found sources for that GUI, I suspect it is closed source (anyone knows the license? github url for it?). Now regarding “high entropy passphrases” and “easily”:

According to https://gitlab.com/cryptsetup/cryptsetup/-/wikis/FrequentlyAskedQuestions#5-security-aspects:

"Plain dm-crypt: Use > 80 bit. That is e.g. 17 random chars from a-z or a random English sentence of > 135 characters length.

LUKS1 and LUKS2: Use > 65 bit. That is e.g. 14 random chars from a-z or a random English sentence of > 108 characters length."

I would argue we are in between those two cases, see below. In general, it is advisable to read that section leading to entropy estimation.

For me, typing 16-17 random chars does not sound “easy”.

BTW, “For opening LUKS container: a. get user password from user’s input b. generate user key from password and salt” is exactly what Cryptsetup-LUKS does (with a volume specific salt), then using this “user key” for en- and decryption of the specific LUKS-volume. You just want to add another indirection with an additional key from a different source.

Yes, LUKS does that precisely. This is done to make brute force attack harder. On my PC, it is 133000 iterations. How many iteration does it do on phone? I would expect way less. Which means that brute force attack would be that many times easier. And which indicates that we have to look on the higher estimates for that password length.

Idea behind iterations used in my scheme was to tie it your phone. If LUKS password is 32 byte, brute forcing that becomes impractical. By being able to make iterations on your phone only via TEE (or SE) only, makes your simple password way harder to attack via iterations.

As I once pointed out, I am convinced, that the enhancements you are aiming at are absolute overkill with the current state of security in SailfishOS and its infrastructure

Taking into account length of reasonable LUKS passwords, I would argue that there is no point in stopping mid-way and adding just alphanumeric passwords. As for going for overkill, argument is to fix it properly when fixing and then deal with other issues.

The attacks via stores are different to the attack considered here. Ironically, work on Chum repos actually improves store attacks somewhat. But it is not a subject for disk encryption, I think.

In principle, it is defence against someone stealing yor phone and passing it over to those who specialize on ID theft. I don’t know how large fraction of stolen devices are going through break in treatment. Maybe none. But I don’t want to keep a device way open welcoming parsing the files/accounts in such case.

Jolla better invests their time to alleviate the real, pressing security issues SFOS and its infrastructure have, instead of designing, implementing and deploying an overly complex crypto scheme.

This initiative is not from Jolla, so maybe their investments do go in the right targets. As for being overly complex, I don’t think it is. Let’s see if I am right in amount of work estimate.

I am surely becoming bashed again for this …

I hope not. As your feedback is very constructive and to the point. Thank you!

For other comments by others - I will come back to them later, as soon as I get time.

3 Likes

data is encrypted only if phone is switched off… but honestly, how often do we have it at that state

If your device is protected by PIN and gets stolen, easiest way to get data is to reboot it into recovery and dump fcontainer to SD card. Then brute force open it and go through your storage . This proposal makes it unfeasible . Obviously , if you don’t have lockscreen protection, no encryption on rest is needed (or effective ).

Re SD card encryption : one step in a time :). That you probably don’t want to tie to device, so long alphanumeric password would be in use. In some respect , SD card issue is separate and can be tackled by separate app… Haven’t thought about it much as I backup usin kopia these days.

Re GUI: as I suspect current GUI is closed source , new one is needed anyway .

It has some home encryption support via cryptsetup, but it is somewhat different .

1 Like

I run systemd-homed on my home PC and its LUKS2 encrypted. So there is encryption. But i have no idea what it uses to encrypt the data with (ie my password or if it does something else).
But i suspect you already looked into that. :slightly_smiling_face:

This may have already been discussed but if the salt is stored in /etc (which is not encrypted) and the k is known then the effective key is still just as weak as the x digits that went into it originally and 6 digits even if they are alphanumeric is practically non-existent keyspace, current recommendations are minimum 12 characters (and that is considered weak).

Edit: That being said I understand that typing a full passphrase for a LUKS volume on a cellphone would be a royal pain in the rear but allowing for the false perception of security is not a solution to this, if it is possible to have the key stored in the SoC and retrieved by say biometrics that may be a solution though I expect a lot of people won’t like that one a lot either.

Edit 2: You could use something like an (NFC) yubikey to store the key maybe…

1 Like

I agree with all these points.

Until software audits of existing subsystems pass muster, the passphrase initiative would get us actual mileage.

As to the usability of longer passphrases, poems work for me. Typing them with your thumbs is a bit of a pita, but …

The jolla folk are certainly putting more and more emphasis on the sandboxing efforts for apps which also seems to be a thing that might mitigate the dangers from the remote apps angle?

Still, thanks for the effort, y’all!

EDIT: should https://forum.sailfishos.org/t/urgent-but-simple-to-implement-additions-on-encryption-in-sfos not be considered in this attempt at recommendations?

EDIT2: and as remote points out in the first edit: The Endless Conundrum of creating a secure PinePhone | Dalton Durst has a really nice summary of the problem domain… especially the two passphrase idea, long LUKS passphrase on boot, shorter key for unlock screen.

EDIT3: um, no one mentioned a detached LUKS header? Did I miss something, just re-read the thread… but that might be a luks2 thing and we’re using luks1?

2 Likes

Security is definitely in Aurora/Rostelecom’s remit though I can’t imagine them wanting >8 char passwords. I think they’re the main reason we got encryption in the first place.
Rostelcom won’t be interested in more Android blobs as their whole point of using SFOS is to not use Android/iOS.

I believe SFOS was only broken by hackers going through the Recovery Console and downloading the encrypted partition. This just bypasses any limits on attempts.
We ideally should be able to re-lock our bootloaders – with this being toggle-able from within Settings. It’s notable that unlock-friendly phone manufacturers don’t offer this as bugs could lead to a bricked phone.

Increasing the key complexity helps but is much more annoying for users.
Security measures should be both optional and potentially bulletproof. I personally don’t need encryption. [Nor do I want to have to log-in to my own phone.]

Failing relocked bootloaders, those who need high security could insist on alphanumeric pass + fingerprint scanner (+ dongle?) ie something you know, something you are, something you have.

There’s also the case for having two levels of lockout. The standard 30s lockout and something like a “Going through TSA” lockout. The latter would eg wipe the salt and it could only be recovered with fingerprint/dongle etc.

Edit: clarified Aurora vs user priorities. @rinigus : didn’t realise you were planning on coding this yourself! Awesome if it works.