Since commit 08f4bdfe98 ("Don't use a secdiscardable file for keys
encrypted by SP") (https://r.android.com/2242561), some keys don't use a
secdiscardable file. Currently if such a key is destroyed, an ERROR
message like the following is logged:
E secdiscard: Secure discard open failed for: /data/misc/vold/user_keys/ce/14/current/secdiscardable
This case is expected, so it should not be an ERROR. Fix this by only
passing the secdiscardable file to the secdiscard program if it exists.
Bug: 232452368
Change-Id: I490289dfdaf0db6c3f4fb507509095e0033e2f69
On the first boot after an upgrade, ensure that any Keystore key
deletions triggered by fscrypt_set_user_key_protection() are deferred
until the userdata filesystem checkpoint is committed, so that the
system doesn't end up in a bad state if the checkpoint is rolled back.
Test: see I77d30f9be57de7b7c4818680732331549ecb73c8
Bug: 232452368
Ignore-AOSP-First: depends on other changes in internal master
Change-Id: I59b758bc13b7a2ae270f1a6c409affe2eb61119c
As a small optimization and code simplification, stop reading and
writing the "stretching" file alongside each stored key. vold never
does key stretching anymore.
There was one special case in the code where if the stretching file
existed and contained "nopassword", then the secret was ignored.
However, this didn't seem to be of any use, especially since it didn't
cause Keystore to be used, so it did *not* allow a key stored with no
secret to be read if a secret was unexpectedly provided.
Bug: 232452368
Bug: 251131631
Bug: 251147505
Change-Id: I5a7cbba7492526e51c451f222b9413d9fae6bce5
Storage keys that are encrypted by the user's synthetic password don't
need to be securely deletable by vold, since secure deletion is already
implemented at a higher level: the synthetic password protectors managed
by LockSettingsService. Therefore, remove the use of the secdiscardable
file by vold in this case to improve performance.
Bug: 232452368
Bug: 251131631
Bug: 251147505
Change-Id: I847d6cd3b289dbeb1ca2760d6e261a78c179cad0
When generating a CE key, don't persist it immediately with
kEmptyAuthentication. Instead, cache it in memory and persist it later
when the secret to protect it with is given. This is needed to make it
so that the CE key is always encrypted by the user's synthetic password
while it is stored on-disk. See the corresponding system_server changes
for more information about this design change and its motivation.
As part of this, simplify vold's Binder interface by replacing the three
methods addUserKeyAuth(), clearUserKeyAuth(), and
fixateNewestUserKeyAuth() with a single method setUserKeyProtection().
setUserKeyProtection() handles persisting the key for a new user or
re-encrypting the default-encrypted key for an existing unsecured user.
Bug: 232452368
Ignore-AOSP-First: This depends on frameworks/base changes that can only
be submitted to internal master, due to conflicts.
Test: see Ia753ea21bbaca8ef7a90c03fe73b66c896b1536e
Change-Id: Id36ba8ee343ccb6de7ec892c3f600abd636f6ce5
Hardware-wrapped inline encryption keys (a.k.a. "wrapped storage keys"
or "TAG_STORAGE_KEY keys") are being generated with rollback resistance
enabled, but are never deleted. This leaks the space that KeyMint
implementations reserve for rollback-resistant keys, e.g. space in the
RPMB. This is a problem especially for the per-boot key, as that gets
regenerated every time the device is rebooted. After enough reboots,
KeyMint runs out of space for rollback-resistant keys. This stops any
new or upgraded keys from being rollback-resistant, reducing security.
This bug affects all devices that use HW-wrapped inline encryption keys
for FBE (have "wrappedkey_v0" in the options for fileencryption in their
fstab), and whose KeyMint implementations support TAG_STORAGE_KEY in
combination with TAG_ROLLBACK_RESISTANCE. But it's more of a problem on
devices that are rebooted frequently, as per the above.
Fix this bug by not requesting rollback resistance for HW-wrapped inline
encryption keys. It was a mistake for these keys to ever be rollback-
resistant, as they are simply a stand-in for raw keys. Secure deletion
instead has to happen higher up the stack, via the Keystore key that
encrypts these keys being deleted, or via the Keystore key and/or Weaver
slot needed to decrypt the user's synthetic password being deleted.
(It was also a mistake for HW-wrapped inline encryption keys to use
Keystore at all. The revised design for them that I'm working on for
upstream Linux doesn't use Keystore. But for now, Android uses Keystore
for them, and the fix is to not request rollback resistance.)
Bug: 240533602
Fixes: 3dfb094cb2 ("vold: Support Storage keys for FBE")
Change-Id: I648a1af9e16787dfcfeefa2b2f2e4a72cac2c6a6
This patch adds more error logging to mountFstab. In a few cases, the
were error paths with no existing error logs. In other cases, the log
messages are there to help understand error flow in logs (for example
when a function with lots of error paths returns false).
Bug: 205314634
Test: treehugger builds
Change-Id: I464edc6e74ea0d7419ee9d9b75fd238752c13f4f
This reverts commit 2601eb7f8c.
Ignore-AOSP-First: reverted change was introduced in sc-dev
Bug: 196887752
Test: R11 boots on master
Reason for revert: R11 boot failure on master
Change-Id: I8d2f566f3991f30cd65c48d959d26df8b6c85f32
If KM is upgraded from a version that does not support rollback
resistance to one that does, we really want our upgraded keys to
include rollback resistance. By passing this tag in when we use the
keys, we ensure that the tag is passed into the upgradeKey request
whenever it is made, which some KM implementations can use to add
rollback resistance to our keys.
Bug: 187105270
Ignore-AOSP-First: no merge path to this branch from AOSP.
Test: Manual
Change-Id: I6154fe26a10b60cd686cc60dbc2e0a85c152f43b
Now that vold uses Keystore2 rather than the Keymaster HAL directly, and
also the new version of Keymaster is called "KeyMint" instead, replace
most of the references to Keymaster in vold with Keystore.
(I decided not to include the "2" in most places, as it seemed
unnecessarily precise in most places, and it would be something that
might need to keep being updated. Only Keystore.{cpp,h} really need to
care about the version number.)
I didn't rename many things in cryptfs.cpp, as that file will be going
away soon anyway. I also left "wait_for_keymaster" and "vdc keymaster
earlyBootEnded" as-is for now, as those are referenced outside vold.
Bug: 183669495
Change-Id: I92cd648fae09f8c9769f7cf34dbf6c6e956be4e8
storeKey() is no longer used outside KeyStorage.cpp, so make it a static
function. Also fix the documentation for storeKey() (e.g. it's no
longer safe to directly move/rename directories created by storeKey() --
one must use RenameKeyDir() instead).
No functional changes.
[ebiggers@ - cleaned up slightly from satyat@'s original change]
Bug: 190398249
Change-Id: I85918359e77bef414dfddfe5ded30fcde6514013
Make fixate_user_ce_key() use RenameKeyDir() to rename key directories
so that any deferred commits for these directories are also updated
appropriately.
This fixes a potential lost Keymaster key upgrade if a key were to be
re-wrapped while a user data checkpoint is pending. This isn't a huge
issue as the key will just get upgraded again, but this should be fixed.
[ebiggers@ - cleaned up slightly from satyat@'s original change]
Bug: 190398249
Change-Id: Ic6c5b4468d07ab335368e3d373916145d096af01
Comparing paths is error-prone (e.g. "/foo/bar" vs "/foo//bar"), so
entries in key_dirs_to_commit are compared using inode and device
number. However RenameKeyDir() breaks this rule and compares raw paths.
Avoid this quirk by finding the entry in the list to replace before
doing the rename.
This doesn't fix any known problem, as vold is fairly consistent with
its paths in practice; this is just a robustness improvement.
Bug: 190398249
Change-Id: I3ce2c0119cb2012ac9d12849570e56600bc23867
storeKeyAtomically() stores keys in a temp directory before renaming
that directory to the real target directory. However when the key is
stored in the temporary directory, the Keymaster storage key might get
upgraded, and it's possible that the temp directory is scheduled for a
deferred commit. storeKeyAtomically() renames that temp directory, but
doesn't update the list of directories marked for deferred commit.
This patch fixes this by removing the temp directory from the list and
adding the real target directory to that list instead.
This bug was found when trying to switch from using the guest keymint to
using the host remote keymint implementation on cuttlefish
(aosp/1701925). The device triggers this bug (and boots to recovery)
when aosp/1701925 is cherry-picked.
Co-Developed-By: Eric Biggers <ebiggers@google.com>
Test: Cuttlefish boots with and without aosp/1701925
Change-Id: I3b6fd6ad32ed415da94423cca6f5a121c16472f2
Now that the salt and hardware auth token related code has been removed,
we can remove the associated (and now unused) constants.
Also cleanup some comments and remove includes related to hardware auth
token support.
Bug: 181910578
Test: Cuttlefish boots.
Change-Id: I3733d5c6bbf6989adc165c554ee53faa2484f4b6
stretchSecret() no longer uses the "salt" parameter, so remove it and
simplify callers
Bug: 181910578
Test: Cuttlefish boots.
Change-Id: Ic2d0742b22b98a66da37f435e274c9d385b8e188
Make vold use keystore2 for all its operations instead of directly using
keymaster. This way, we won't have any clients that bypass keystore2,
and we'll no longer need to reserve a keymaster operation for vold.
Note that we now hardcode "SecurityLevel::TRUSTED_ENVIRONMENT" (TEE)
when talking to Keystore2 since Keystore2 only allows TEE and STRONGBOX.
Keystore2 presents any SOFTWARE implementation as a TEE to callers when
no "real" TEE is present. As far as storage encryption is concerned,
there's no advantage to using a STRONGBOX when a "real" TEE is present,
and a STRONGBOX can't be present if a "real" TEE isn't, so asking
Keystore2 for a TEE is the best we can do in any situation.
The difference in behaviour only really affects the full disk encryption
code in cryptfs.cpp, which used to explicitly check that the keymaster
device is a "real" TEE (as opposed to a SOFTWARE implementation) before
using it (it can no longer do so since Keystore2 doesn't provide a way
to do this).
A little code history digging (7c49ab0a0b in particular) shows that
cryptfs.cpp cared about two things when using a keymaster.
- 1) that the keys generated by the keymaster were "standalone" keys -
i.e. that the keymaster could operate on those keys without
requiring /data or any other service to be available.
- 2) that the keymaster was a non-SOFTWARE implementation so that things
would still work in case a "real" TEE keymaster was ever somehow
added to the device after first boot.
Today, all "real" TEE keymasters always generate "standalone" keys, and
a TEE has been required in Android devices since at least Android N. The
only two exceptions are Goldfish and ARC++, which have SOFTWARE
keymasters, but both those keymasters also generate "standalone" keys.
We're also no longer worried about possibly adding a "real" TEE KM to
either of those devices after first boot. So there's no longer a reason
cryptfs.cpp can't use the SOFTWARE keymaster on those devices.
There's also already an upgrade path in place (see
test_mount_encrypted_fs() in cryptfs.cpp) to upgrade the kdf that's
being used once a TEE keymaster is added to the device. So it's safe for
cryptfs.cpp to ask for a TEE keymaster from Keystore2 and use it
blindly, without checking whether or not it's a "real" TEE, which is why
Keymaster::isSecure() just returns true now. A future patch will remove
that function and simplify its callers.
Bug: 181910578
Test: cuttlefish and bramble boot. Adding, switching between, stopping
and removing users work.
Change-Id: Iaebfef082eca0da8a305043fafb6d85e5de14cf8
HardwareAuthTokens are no longer used by vold since Android P. So remove
the auth token parameter from vold. This patch doesn't remove the token
from IVold.aidl, and the methods in VoldNativeService.cpp return an
error if a non-empty auth token is passed to them.
Bug: 181910578
Test: cuttlefish and bramble boot with patch
Change-Id: I1a9f54e10f9efdda9973906afd0a5de5a699ada5
The error messages that are printed when probing for rollback resistance
support on a device that doesn't support rollback-resistant keys can
make it sound like something is going wrong. Print a WARNING message
afterwards to try to make it clear what is going on. Also adjust or add
DEBUG messages when starting to generate each key so that it's easier to
distinguish the log messages for different key generation operations.
Bug: 182815123
Test: boot on device that doesn't support rollback-resistant keys and
check log.
Change-Id: I37a13eb5c1e839fb94581f3e7ec1cd8da0263d2b
When an FBE or metadata encryption key is created, it's important that
it be persisted to disk right away; otherwise the device may fail to
boot after an unclean shutdown. storeKey() has the needed fsync()s.
However, storeKeyAtomically() doesn't, as it doesn't fsync() the parent
directory of key_path after it renames tmp_path to it.
Two callers do fsync() the parent directory themselves, but others
don't. E.g., the metadata encryption key doesn't get properly synced.
Therefore, add the needed fsync() to storeKeyAtomically() so that it
gets done for everyone.
Also remove the now-unneeded fsync()s from the two callers that did it
themselves.
Change-Id: I342ebd94f0a3d2bf3a7a443c35b6bda0f12e1ab2
With this change, vold exposes an API that may be used to bind key
storage encryption keys to a given seed value. The seed value passed to
vold must be consistent across reboots, or key storage keys will not be
derived consistently. The seed is expected to be set very early in boot,
prior to the use of any key storage encryption keys.
This feature is intended to be used for embedded applications such as
in autos, where the seed may be provided by some other component of the
system. In such systems, there is a default user that is automatically
signed in without a PIN or other credentials. By binding the file
encryption to a platform-provided seed, the default user's data gains
additional protection against removal of the Android embedded device
from the integrated system.
Bug: 157501579
Test: Set seed at startup via init.rc. Seed changes fail as expected.
Change-Id: I9b048ec5e045b84c45883724ace2356d4ef6244d
Remove the error-prone 'keepOld' parameter, and instead make begin()
(renamed to BeginKeymasterOp()) do all the key upgrade handling.
Don't handle /data and /metadata differently anymore. Previously, when
a checkpoint is active, key blob files were replaced on /data
immediately; only the actual Keymaster key deletion was delayed until
checkpoint commit. But it's easier to just delay the key blob file
replacement too, as we have to implement that for /metadata anyway.
Also be more vigilant about deleting any leftover upgraded keys.
Test: Tested on bramble using an OTA rvc-d1-release => master. In OTA
success case, verified via logcat that the keys were upgraded and
then were committed after the boot succeeded. In OTA failure
case, verified that the device still boots -- i.e., the old keys
weren't lost. Verified that in either case, no
keymaster_key_blob_upgraded files were left over. Finally, also
tried 'pm create-user' and 'pm remove-user' and verified via
logcat that the Keymaster keys still get deleted.
Change-Id: Ic9c3e63e0bcae0c608fc79050ca4a1676b3852ee
Generate a storage key without rollback_resistance when device doesnt
support the corresponding tag.
Bug: 168527558
Change-Id: Iaf27c64dba627a31c9cbd9178458bf6785d00251
To prevent keys from being compromised if an attacker
acquires read access to kernel memory, some inline
encryption hardware supports protecting the keys in
hardware without software having access to or the
ability to set the plaintext keys. Instead, software
only sees "wrapped keys", which may differ on every boot.
'wrappedkey_v0' fileencryption flag is used to denote
that the device supports inline encryption hardware that
supports this feature. On such devices keymaster is used
to generate keys with STORAGE_KEY tag and export a
per-boot ephemerally wrapped storage key to install it in
the kernel.
The wrapped key framework in the linux kernel ensures the
wrapped key is provided to the inline encryption hardware
where it is unwrapped and the file contents key is derived
to encrypt contents without revealing the plaintext key in
the clear.
Test: FBE validation with Fscrypt v2 + inline crypt + wrapped
key changes kernel.
Bug: 147733587
Change-Id: I1f0de61b56534ec1df9baef075acb74bacd00758
This CL updates vold to use the Keymaster 4.1 interface, but does not
yet call any of the new methods.
Test: Boot the device
Change-Id: I4574a2f6eead3b71d1e89488b496b734694620c7
Merged-In: I4574a2f6eead3b71d1e89488b496b734694620c7
Don't delete keys in checkpointing mode. Instead wait until the
checkpoint has been committed.
Bug: 134631661
Test: Flash A with a working build. Flash B with a broken build. Test
that the device rolls back to A without getting sent to recovery.
Merged-In: Ie5fc2d098355e2d095c53e9a95a6a8c7ab7ed051
Change-Id: Ie5fc2d098355e2d095c53e9a95a6a8c7ab7ed051
Remove static definition of writeStringToFile, and
move it from KeyStorage to Utils
(cherry picked from commit 0bd2d11692)
Bug: 71810347
Test: Build pass and reboot stress test.
Change-Id: I38bfd27370ac2372e446dc699f518122e73c6877
Merged-In: I38bfd27370ac2372e446dc699f518122e73c6877
The boot failure symptom is reproduced on Walleye devices. System boots
up after taking OTA and try to upgrade key, but keymaster returns "failed
to ugprade key". Device reboots to recovery mode because of the failure,
and finally trapped in bootloader screen. Possible scenario is:
(After taking OTA)
vold sends old key and op=UPGRADE to keymaster
keymaster creates and saves new key to RPMB, responses new key to vold
vold saves new key as temp key
vold renames temp key to main key -------------- (1) -- still in cache
vold sends old key and op=DELETE_KEY to keymaster
keymaster removes old key from RPMB ------------ (2) -- write directly to RPMB
==> SYSTEM INTERRUPTED BY CRASH OR SOMETHING; ALL CACHE LOST.
==> System boots up, key in RPMB is deleted but key in storage is old key.
Solution: A Fsync is required between (1) and (2) to cover this case.
Detail analysis: b/124279741#comment21
Bug: 112145641
Bug: 124279741
Test: Insert fault right after deleteKey in vold::begin (KeyStorage.cpp),
original boot failure symptom is NOT reproducible.
Change-Id: Ib8c349d6d033f86b247f4b35b8354d97cf249d26
This adds the ability to upgrade a key and retain the
old one for rollback purposes. We delete the old key
if we boot successfully and delete the new key if we
do not.
Test: Enable checkpointing and test rolling back
between two versions
Bug: 111020314
Change-Id: I19f31a1ac06a811c0644fc956e61b5ca84e7241a
This CL changes vold from using a KM3 device directly to using the KM4
support wrapper from the KM4 support library, which supports both KM3
and KM4 devices (KM0, 1 and 2 devices are still supported as well,
because the default KM3 device is a wrapper that uses them).
In addition, I found myself getting confused about which "Keymaster"
types were locally-defined vold keymaster types and which were from
the KM4 HAL and support library, so I changd the approach to
referencing the latter, so all of them are qualified with the "km::"
namespace reference.
Test: Build & boot
Change-Id: I08ed5425641e7496f8597d5716cb3cd0cbd33a7f