Drive-Trust-Alliance / sedutil

DTA sedutil Self encrypting drive software
610 stars 235 forks source link

Sleep support #90

Open lulkipvx opened 8 years ago

lulkipvx commented 8 years ago

Are there any plans for sedutil to support HDD sleep? This is the single most feature that has got me disabling sedutil currently.

goldcove commented 8 years ago

This has been addressed earlier and I agree that this is a feature that is sourly missing. I believe it requires a kernel driver... and someone to make it :-) Se issue #69

tarruda commented 7 years ago

I've also faced this issue with my EVO 850 and ended up leaving the drive unlocked(Rather not use LUKS/dmcrypt because it disables ssd optimizations done by filesystems). Also see #8

In my research, I've found an article regarding this subject: https://www.winmagic.com/blog/2014/09/17/sleep-and-pba/. Winmagic is a windows-only encryption solution that has full support for self encrypting drives while still supporting the S3 state. This is the relevant part of the article:

sleep is a low power mode where memory is kept active but the screen, drive and other hardware are powered off to save battery life. When the user hits the power button the machine jumps back to life very quickly because everything is already in memory. In the case of software FDE this includes the DEK (Data Encryption Key) or with Self-Encrypting Drives (SED) the credential required to unlock the drive

What I think could be done to have full S3 support is write a kernel module that:

This should be a reasonable security compromise for most users since the random password is only valid while the computer is sleeping, and only exists in memory, much like software FDE. If the computer runs out of power while sleeping, the random password will be erased from memory and only the user can unlock the disk again.

I currently have little knowledge on how to write kernel modules, much less to achieve this task, but I hope to find time to learn/implement this in the future.

goldcove commented 7 years ago

Generates a random password before the computer goes to sleep

If a kernel driver is made you just need to interrupt the resume process early (before the OS tries to access the disk, and ask the user for the passphrase and unlock the drive.

Storing a temporary password on disk should be avoided.

goldcove commented 7 years ago

Some info on a kernel patch for this issue, altough this is for Intel NVMe: https://lkml.org/lkml/2016/5/18/667 https://firmwaresecurity.com/2016/04/23/new-intel-patch-adding-tcg-opal-unlock-to-linux-nvme/

tarruda commented 7 years ago

altough this is for Intel NVMe:

On another post in the same thread the OP suggests it is possible to make the OPAL code outside of the NVME driver so it can support other devices.

bhack commented 7 years ago

Is it merged in 4.11?

bhack commented 7 years ago

4.11 is officially released. Can we update the docs or close this?

kylemanna commented 7 years ago

Looks like it is merged.

@bhack Did you write something to call ioctl(IOC_OPAL_SAVE) to save the key in the kernel?

bhack commented 7 years ago

Is this project still active?

cristim commented 7 years ago

@bhack the last code change by DTA is about 11 months old, but the community seems quite active, discussing issues and submitting pull requests which were all ignored so far so all the code improvements exist in various unmerged forks.

There were some discussions about this situation and in order to exit this somehow, I forked the project under a new organization, so it's now available at https://github.com/sedutil/sedutil and will be governed as a meritocracy. The most active fork and PR authors were already given admin rights and can drive the project forward.

I propose everyone interested to join us there, hopefully together we'll be able to address all the current issues.

Later edit: DTA resumed development and the sedutil/sedutil fork is no longer maintained.

kylemanna commented 7 years ago

I started down this path, and sent the hashed password to the kernel, but the resume locking problem miraculously disappeared.

jthomaschewski commented 7 years ago

@kylemanna just to clearify: Are you using an unpatched build of sedutil and kernel 4.11 successfully with S3 resume? If yes: Do you have an NVMe disk or SATA?

Thanks

kylemanna commented 7 years ago

Are you using an unpatched build of sedutil and kernel 4.11 successfully with S3 resume?

I'm using a patched build of the PBA, you can find the PBA as well as code on my fork.

I'm running the testing build of 4.11.1 kernel for Arch linux, no changes by me. I just built it.

If yes: Do you have an NVMe disk or SATA?

I'm using a Samsung 960 EVO 1TB which is a NVMe drive in M.2 2280 form factor.

Also, I have semi-coherent babbling about my experience on my blog which may reveal more details for those interested

cristim commented 7 years ago

@ScottyBauer is one of the authors of the Linux kernel OPAL implementation, hopefully he can explain how to get S3 to work on Linux with a sedutil-based setup.

ScottyBauer commented 7 years ago

Hi, give me some time to read through the thread and I'll publish some comments.

ScottyBauer commented 7 years ago

So, Christoph implemented some changes to get Opal working (in the Linux kernel) with SATA drives, it will be published with 4.13 I believe, but you can grab Linus' tree and give it try. NVMe was supported from 4.11 like others pointed out.

We have a project here: https://github.com/ScottyBauer/sed-opal-temp

Which will let you interface with the ioctls to setup unlock-from suspend. After you build that project you would issue the following command:

./sed-opal sed-save /dev/nvme0n1 --lr 1 --user user1 --locktype RW --password bla

or ./sed-opal sed-save /dev/nvme0n1 --lr 1 --user admin1 --locktype RW --password bla

where LR is your locking range lock type is "unlock for RW" and password is w/e your PW is. You can then suspsend your laptop and bring it back out and it should work. This will work with any NVME/Opal compliant drive, Intel, Samsung etc. Since in the linux kernel we have to make it work for everyone not just Intel :).

If anyone wanted to port the ioctls to DTA sedutil that would be fine too. You wouldn't have to port everything just the OPAL_SAVE ioctl since we replicated a lot of functionality in-kernel due to business requirements, as well as licensing issues.

You can create a locking range with sedutil and unlock it in the kernel no problem as well. So long as you provide the same passwords to both.

r0m30 commented 7 years ago

@ScottyBauer Thanks, forked the repo will take a look. Will probably only implement the OPAL_SAVE ioctl, it will be less messy in my codebase.

Are Jason and Rafael still there?

cristim commented 7 years ago

@ScottyBauer thanks, that's great, I will give it a try.

The only minor usability issue I see is having to ensure the password is encoded the same way as with sedutil.

anoother commented 7 years ago

@ScottyBauer Nice work!

It reads like this currently unlocks the laptop on wake -- is that correct? How much more work would be involved in allowing it to prompt for the pw on wake?

kuro68k commented 7 years ago

I tested it on an NEC laptop and it worked. Thanks a lot for your effort!

@anoother That sounds like a lot of work. When the machine wakes up it is difficult to present anything before the disk is unlocked. If you need that level of security I suggest using hibernation rather than sleep mode. Also some Ryzen parts now feature encrypted RAM which complements this nicely.

ScottyBauer commented 7 years ago

Yeah it's pretty much impossible to have a prompt issued to the user after an S3. That's why we have to unlock via the kernel. Userland hasn't been awoken yet and userland being woken up is contingent on the drive being unlocked or the file systems will BUG(). @kuro68k is right you can potentially modify the SED code a bit to store the PWs in an SGX or w/e AMD has now a days if you're paranoid. But for now if you want a prompt you should hibernate.

Venemo commented 7 years ago

So if I just use kernel 4.13 and compile the repo from @ScottyBauer and run ./sed-opal sed-save /dev/sda --lr 1 --user admin1 --locktype RW --password mypassword on every bootup, then sleep / resume will just work with an OPAL SATA SSD?

ScottyBauer commented 7 years ago

Yeah It should. I never tested Christoph's patches, so if you run into issues do dmesg -n8, retry the commands and post submit a report to me or Christoph.

cristim commented 7 years ago

I couldn't get it working yet.

Is sed-save using the same password encoding scheme used in sedutil? Or am I missing something else?

Venemo commented 7 years ago

@cristim Apparently not. See the blog post by @kylemanna linked above. @ScottyBauer Interestingly, sed-opal always says Success regardless of what password I give it :( Is this a known issue?

ScottyBauer commented 7 years ago

@cristim Sed-util runs a hash on your password then sends it off to the device. The kernel can accept that hashed password, but it doesn't do it manually. If you setup the locking range with sed-util you'll have to hash the password and send that to the kernel for sed-save.

ScottyBauer commented 7 years ago

@Venemo That sounds familiar, but I did fix a bug here: https://kernel.googlesource.com/pub/scm/linux/kernel/git/axboe/linux-block/+/2d19020b085eaf61d24377db27e8630cd9cff7ce

It (that fix) should be in every kernel with this. Can you rerun your commands after doing a dmesg -n8 (as root).

If you're providing an incorrect password to the kernel for OPAL_SAVE command it will always return success. We don't query the TPER for OPAL_SAVE we just hold onto the password for an S3 resume. If you provide an incorrect password OPAL_SAVE will say success but the kernel will fail to unlock from S3.

Venemo commented 7 years ago

@cristim I made some fixes to the tool made by @kylemanna and using that, I could make it work. Now I can sleep with my OPAL SSD!

Venemo commented 7 years ago

@ScottyBauer Yes, that's exactly what happened with me. Now that I figured out the exact hashed password I could make it work on kernel-4.13.0-0.rc6.git4.2.fc28.x86_64.

EDIT: here is the code https://github.com/Venemo/opalctl based on work by @kylemanna

ScottyBauer commented 7 years ago

@Venemo Can you link directly to @kylemanna 's changes, please?

Venemo commented 7 years ago

@ScottyBauer Sure, here it is: https://github.com/kylemanna/opalctl

cristim commented 7 years ago

Thanks guys!

To summarize:

Both tools have an usability problem. They may work for kernel hackers, but in order for this to be usable by ordinary people with sedutil-configured drives we need a tool which:

Venemo commented 7 years ago

@cristim Yes, opalctl is just a small hack to make sure it can be made to work, it is obviously not a proper solution, and definitely not for end users. It could be possible however to make a simple tool (with maybe a systemd service unit to run at bootup) which does this.

Venemo commented 7 years ago

@cristim The real problem is that making a really end-user-friendly solution would be hard. And then you still have the problem of whether to store the password on the disk (so that you can tell the kernel how to unlock your OPAL drive), or maybe somewhere else or maybe ask the user for the OPAL password on every suspend-resume cycle... this sort of stuff always leads to lots of heated debate.

But with some compromises (eg. if you are okay with storing the password hash on the disk, maybe in gnome-keyring) it could be reasonalby simple to create a simple tool which adds sleep support to your OPAL-enabled drive.

However, I'm not sure if it's possible to make the setup user friendly. I'm mostly sure that with the new kernel ioctls it's possible to add OPAL setup to distro installers like Anaconda (they already offer LUKS, so this could be a switch next to that), but I'm not sure if it's possible to set up once you are running off the drive. At least, before using the rescue image, I tried to set it up from my main distro running from the disk itself, but it didn't really work.
By comparison, I'm also not sure if it's possible to set up LUKS while running off the disk, I'd think probably not.

kuro68k commented 7 years ago

Storing the password/key is what TPM modules are for. Even without TPM support, modern CPUs support encrypted RAM now, and even without that having they key in unencrypted RAM is still better than not having an encrypted drive.

Resume from suspend is no problem because the PBE is executed again.

cristim commented 7 years ago

Even without a TPM, we store passwords on the disk all the time, I still have /etc/shadow on my machine. I don't think this is a problem, assuming the hash is long enough and using a salt.

I don't see why we couldn't use the same principle in the PBA. As a salt we could perhaps use the serial number of the drive or something similar.

ScottyBauer commented 7 years ago

What was the purpose of hashing the password before doing the pass through in DTA sed util? I never really understood that. Hashing the password, aside from making it longer, doesn't really get you anything security wise. If the kernel is holding a hashed password instead of plaintext it doesn't matter because the hashed password is the pw that unlocks the drive. The hashed password is essentially now the "plaintext" pw.

Venemo commented 7 years ago

@ScottyBauer I guess it's the same reason why hashing is a good reason anywhere else: even if they steal it, they only steal the salted hash, and not your password. So your password remains a secret and they can't use it to get into other places where you use the same password.

That is just a guess though, I'm not a member of the sedutil team, so not sure why they chose to do it this way.

Venemo commented 7 years ago

@ScottyBauer This is interesting. After a while of using IOC_OPAL_SAVE I noticed that after a sleep-resume cycle Linux sees the contents of the PBA in /dev/sda1 instead of its own EFI stuff. What can I do to fix this?

EDIT: manually running sedutil-cli --setmbrdone on MyAwesomePassword /dev/sda after resume fixes it.

Venemo commented 7 years ago

But shouldn't the kernel also do the setmbrdone on thing after unlocking the drive?

ScottyBauer commented 7 years ago

From my understanding of the spec only the commands we run for unlock should be necessary. I was under the impression setmbrdone was a one-shot.

You're saying after an unlock you see the PBA on /dev/sda1 instead of what? What does it look like before/after setmbrdone? And before/after boot from PBA. Can you post kernel logs?

I went and looked at the spec 2.0 (4.3.5.3 MBRControl (M)) there is a table in the Locking SP that is DoneOnReset

4.3.5.3.1 Done OnReset Restrictions The TPer SHALL support the following DoneOnReset column values: a) { 0 } (i.e. Power Cycle); and b) { 0, 3 } (i.e. Power Cycle and Programmatic).

The preconfig says that it's disabled by default. So it seems like if we get that enabled your problems will be solved on resets.

Venemo commented 7 years ago

@ScottyBauer Here is how I arrived at that conclusion:

What I noticed was just some general sluggishness, so I went on with iotop to see what's the problem. iotop said that journald was doing considerable IO, so I took a look at journalctl and discovered that it is logging a lot of failed read/write attempts on /dev/sda1 (which is mounted in /boot/efi). An fsck told me the filesystem was corrupt. After an unmount and re-mount, /dev/sda1 contained exactly what the PBA contains. After an unmount, setting setMBRDone, and re-mount, now /dev/sda1 contained what belonged to Fedora's EFI boot partition as expected.

I believe when setMBREnable is on (ie. the shadow MBR is enabled), the drive will activate the shadow MBR on every power cycle. Sleep and resume is just another power cycle for the drive so it cannot differentiate between when you turn on the computer and when the computer returns from sleep. So it displays the shadow MBR until we setMBRDone to on.

Here is how sedutil's PBA handles the same thing:
https://github.com/Drive-Trust-Alliance/sedutil/blob/master/LinuxPBA/UnlockSEDs.cpp#L78 - First it sets setMBRDone when the shadow MBR is enabled, and then it unlocks the drive. I think the same thing should be done by the kernel too.

ScottyBauer commented 7 years ago

That way works, but I don't think its the proper way to accomplish it. I'm going to write some code this weekend (maybe tonight -- I can't do it on company time)to try and toggle the MBRControl table to have it auto on on resets, so there isn't this dependency in S3 path. Will you be willing to test it for me, it's just going to be a patch to DTA sed-util.

Venemo commented 7 years ago

@ScottyBauer Sure, let's try. But then, how does the drive distinguish between a sleep / resume and a normal power off / on cycle? We want to have the shadow MBR in the latter case. (Otherwise can't unlock the drive.)

ScottyBauer commented 7 years ago

There is no difference to the drive. Sleep/resume is the same to the drive as power off / power on. The only difference between the two is the way the OS is brought up.

r0m30 commented 7 years ago

@ScottyBauer mbrdone is supposed to be reset on any power cycle. From Core Spec 2.0: 5.7.2.5.3 Done This value indicates whether the TPer has completed processing the contents of the MBR table. After the occurrence of a reset event that is listed in MBRDoneOnReset, until the host sets the MBRControl table's Done column to True, LBA requests made by the host, for LBA 0 up to the LBA that maps to the end of the MBR table, SHALL only be fulfillable by values from the MBR table. The Done column is set to False on every occurrence of a reset event that is listed in MBRDoneOnReset. The state of Done SHALL NOT affect the capacity of the Storage Device. 5.7.2.5.4 MBRDoneOnReset This column value identifies the reset types that set the Done column to False. The MBRDoneOnReset column identifies the types of resets that cause Done to be automatically set to False. If the set is empty, the device SHALL NOT change the value of the Done column on any reset. At issuance, the default value SHALL be Power Cycle

And the OPAL 2.0 spec: 4.3.5.3.1 DoneOnReset Restrictions The TPer SHALL support the following DoneOnReset column values: a) { 0 } (i.e. Power Cycle); and b) { 0, 3 } (i.e. Power Cycle and Programmatic).

ScottyBauer commented 7 years ago

Yeah so the opal 2.0 spec is saying under 4.3.5.3.1 DoneOnReset Restrictions: part B) power and prog but you can never have power off. Right?

I'll submit a patch tomorrow to check discovery on suspend and see if MBR is enabled, if so I'll set mbr done.

r0m30 commented 7 years ago

The way I read the spec is that you must reset mbrdone on a power cycle , { 0 } in both a and b and you may reset mbrdone on a programmatic reset, { 3 } in b. There is text in the spec that describes what should happen on a programmatic reset and it references DoneOnReset in a conditional (if DoR contains Programmatic then reset mbrdone).

This is also what I've experienced across multiple vendor implementations.

But then again I've had a few interesting conversations with microcode devs.

Venemo commented 7 years ago

Sleep/resume is the same to the drive as power off / power on. The only difference between the two is the way the OS is brought up.

What if you put the laptop to sleep and the battery runs out? Then you'd expect the shadow MBR to be brought up if you turn it on, right?

ScottyBauer commented 7 years ago

I've submitted a patch upstream to fix the MBRDone issue.