11

These are the files that I know go into verifying a user's password:

/data/system/gatekeeper.password.key
/data/system/gatekeeper.pattern.key
/data/system/locksettings.db
/data/system/locksettings.db-shm
/data/system/locksettings.db-wal

I know that this is where the files used construct the FBE key are stored:

/data/misc/vold/user_keys/ce/0/current/version
/data/misc/vold/user_keys/ce/0/current/secdiscardable
/data/misc/vold/user_keys/ce/0/current/encrypted_key
/data/misc/vold/user_keys/ce/0/current/stretching
/data/misc/vold/user_keys/de/0/encrypted_key
/data/misc/vold/user_keys/de/0/stretching
/data/misc/vold/user_keys/de/0/keymaster_key_blob
/data/misc/vold/user_keys/de/0/secdiscardable
/data/misc/vold/user_keys/de/0/version

Although I'm told the encrypted FBE keys are stored in the above paths, these files seem related:

/data/system_de/0/spblob/0000000000000000.handle
/data/system_de/0/spblob/XXXXXXXXXXXXXXXX.pwd
/data/system_de/0/spblob/XXXXXXXXXXXXXXXX.secdis
/data/system_de/0/spblob/XXXXXXXXXXXXXXXX.spblob

The XXXXXXXXXXXXXXXX is a placeholder for a 16-character long hexadecimal "handle"; 0000000000000000.handle, by contrast, is named exactly as it written. There are actually several sets of pwd/secdis/spblob files on my phone and two that are missing their spblob file. I'm not sure I'm supposed to have that many.

Over the pass few days, I've messed up my phone trying to get TWRP to decrypt my data. At first, after removing my password, I couldn't set another one as Settings would crash whenever I tried. I was able to fix it by renaming locksettings.db. I then went ahead and set and cleared several different (but very insecure) passwords/PINs, including my old one (which is secure). I'm unable to remember the order of events, but now I'm at a point where I get Pixel is starting whenever I swipe on my home screen after booting. I'm suspecting this has to do with it not being able to decrypt my FBE key. I'm wondering if through my combination of renaming files like gatekeeper.*.key and locksettings.db that the FBE key maybe was decrypted with the wrong key and then reencrypted with a different one.

I'd like to know what role the above files play in the encrypting my phone. I'd also like to know:

  • What data from what sources is combined using what algorithms to decrypt the keys that encrypt my phone.
  • What happens when the password is changed (e.g., what files are decrypted/reencrypted, whether the salt is changed, etc.).
  • How the files gatekeeper.*.key and locksettings.db used in the process.
  • Whether or not the FBE key ever changes with the password.

The purpose of all of this is to determine if the problem with my lies with the encryption key being wrong or if it's a matter of cleaning up the right files, and to get past the endless Pixel is starting message to my apps and content.

9
  • 1
    page 9+10 may give you some hints (just found this on google i do not understand everything) pdfs.semanticscholar.org/e1cf/…
    – alecxs
    Commented Aug 25, 2019 at 11:32
  • 2
    @alexcs A factory reset will not suffice. I want my data that's on it.
    – Melab
    Commented Aug 25, 2019 at 18:43
  • bear in mind there is a 30 seconds timeout after x attempts (timeout may increase) and twrp will silently fail during this waiting period (even with the right pin) - it can even wipe your data (depends on gatekeeper settings and device)
    – alecxs
    Commented Aug 25, 2019 at 22:09
  • furthermore i am not sure if /data/system ever was accessible (is this unencrypted area?)
    – alecxs
    Commented Aug 25, 2019 at 22:14
  • 1
    @alexcs If the timeout is enforced by Android, then the timeout can be disabled by flashing a ROM that does not enforce it.
    – Melab
    Commented Sep 23, 2019 at 23:22

1 Answer 1

2

Of the files you mentioned above, locksettings.db is actually the least relevant to the decryption process. And, as a result, the easiest to recreate if corrupted or lost. It's simply an SQLite database. It contains the following tables:

CREATE TABLE android_metadata (locale TEXT)
CREATE TABLE locksettings (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT,user INTEGER,value TEXT)
CREATE TABLE sqlite_sequence(name,seq)

The table android_metadata contains a single row, e.g. locale=en_US. The table sqlite_sequence is a counter for the rows in locksettings, and should therefore contain a single row name='locksettings',seq=9

In the table locksettings, only one row is actually relevant to the decryption process. That row is name='sp-handle'. It's matching value is the decimal representation of the hexadecimal value represented by XXXXX in XXXXX.spblob. Put more simply, the only thing locksettings.db does in practice during the decryption process is point at the correct spblob file. This is particularly important if you have several, as each might correspond with a different unlock password.

The spblob file contains something called the "Synthetic Password", which is used to generate the decryption key for the Key Encrypted Key in /data/misc/vold/user_keys/ce/0/current/encrypted_key. encrypted_key is basically an AES-256-GCM encrypted key. The first 12 bytes is the GCM IV, the last 16 bytes is the GCM authentication tag, and everything in between is the cypher text. Once successfully decrypted, the key is added to fscrypt's keychain, and used to decrypt files in user-locked areas of the drive, like /data/data or /data/media. This also involves reading xattribute (9, 'c') on each encrypted file/directory, but this is already down to the filesystem driver. The important point is that you need to decrypt spblob to decrypt /data/misc/vold/user_keys/ce/0/current/encrypted_key to decrypt the rest of the drive.

Not to be confused with /data/misc/vold/user_keys/de/0/encrypted_key which is used to decrypt files/directories that don't require the PIN, such as /data/app or /data/system_de/0. The matching keymaster_key_blob contains the key to decrypt encrypted_key, in bytes 5 through 36 (The rest is header, metadata, and authentication tag), making it significantly easier to decrypt. Naturally, the CE key does not have a matching keymaster_key_blob.

spblob itself starts with 2 bytes representing version and "token type" respectively. The "token type" is 0 for lock screen, 1 for strong hardware token, and 2 for weak hardware token. Generally, it should be 0. The remainder of the bytes are the double AES-256-GCM encrypted synthetic password. The same general format as encrypted_key applies, i.e. First 12 bytes are IV and last 16 are authentication tag. As a result, the size of spblob is the size of the synthetic password plus 2+12*2+16*2=58 bytes.

The "outer" GCM encryption is generated from a hardware-encrypted key, with the application id synthetic_password_XXXXX where XXXXX is the name of the blob with leading 0s trimmed (Comments inside the Android code suggests the 0 trimming might be a bug that was left in because "fixing" it would break the decryption process). An encrypted version of this key should be present in the file /data/misc/keystore/persistent.sqlite, which is also an SQLite database. Decrypting it would require files from the /metadata partition, which is hardware-protected.

Fully describing persistent.sqlite would make this already long answer even longer, so here's the query for getting the encrypted key:

SELECT blob FROM keyentry, blobentry WHERE keyentry.id=blobentry.keyentryid AND keyentry.alias='synthetic_password_XXXXX'

Where XXXXX is the matching spblob file name with leading 0s trimmed.

The most important part is that so long as the phone hasn't been hardware-reset, it should be able to recover the hardware-encrypted key without problem.

The inner encryption of the spblob is where the user PIN comes in. And also where the other files come in. First the file pwd is parsed to get parameters for scrypt KDF algorithm. The user-input PIN is put through scrypt with the parameters extracted from pwd to produce a 32 byte hash called "stretched LSKF". This is combined with a hash of the contents of the secdis file, and then hashed again, to produce the key for decrypting the partially decrypted spblob. The exact formula is:

prefixhash(prefix, message) = sha512(prefix.padEnd(128, '\0') + message)
inner_key = prefixhash('application-id', stretchedLskf + prefixhash('secdiscardable-transform', file-contents('XXXXX.secdis')))
synthetic_password = gcm-decrypt(inner_key, gcm-decrypt(keystore_get('synthetic_password_XXXXX'), file-contents('XXXXX.spblob')[2..]))

So, to answer the original question, to properly decrypt the files, you need:

  1. locksettings.db to point at the correct spblob
  2. The pwd and secdis matching the spblob to be present
  3. The correct PIN matching the spblob
  4. synthetic_password_XXXXX to be present in persistence.sqlite
  5. The /metadata partition to contain the correct key for decrypting synthetic_password_XXXXX. Note that factory reset or flashing a new ROM will very likely wipe the /metadata partition.
  6. The encrypted key /data/misc/vold/user_keys/ce/0/current/encrypted_key, as well as the matching secdiscardable and stretching files, which are used along with the synthetic password in spblob to generate the key necessary to decrypt encrypted_key.

Changing your PIN is most likely to create a new spblob file, and change locksettings.db to point at it. It may delete the old spblob file. It's unlikely to touch the CE encrypted_key as any modification to it runs the risk of corrupting it, rendering all files encrypted with it inaccessible. It would absolutely not attempt to re-encrypt all of the files, as that would both carry a risk of corruption, and also take a very long time. Much longer than anyone would wait for just a PIN change. Also, according to the comments within the code, "A user's SP never changes, but SP protectors can be added and removed", so even if you get new spblob files, the decrypted content of each of them should be the same.

As an aside, I do suggest creating backups of all of these files before doing any more messing around. If at all possible, try to create a backup of the /metadata partition as well, although the hardware may attempt to prevent that. That way, if messing around or guessing wrong PINs causes one of these files to become corrupt or disappear, you can potentially restore it from backup.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .