Drive-Trust-Alliance / sedutil

DTA sedutil Self encrypting drive software
611 stars 236 forks source link

Question about setting locking ranges #433

Open Blacklands opened 1 year ago

Blacklands commented 1 year ago

I'm working on a little tool at the moment to automate unlocking non-boot Opal drives (via sedutil).

I just found out that you can apparently set locking ranges (--setLockingRange) without ever having set them up first. sedutil just reports the same output as always, but this doesn't actually succeed, the drive is still locked.

Here's an example. This is a Samsung 880 Pro.

Locking Range Configuration for \\.\PhysicalDrive2
LR0 Begin 0 for 0
            RLKEna = Y  WLKEna = Y  RLocked = Y  WLocked = Y
LR1 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR2 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR3 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR4 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR5 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR6 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR7 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N
LR8 Begin 0 for 0
            RLKEna = N  WLKEna = N  RLocked = N  WLocked = N

I've only set up locking range 0 on this drive.

Now, if I call --setLockingRange 3 rw, I get back LockingRange3 set to RW. Shouldn't the drive report some sort of error because I never set up locking range 3 (using --setupLockingRange)? Nothing seems to happen, either. And if I --query the drive after this, I still get Locked = Y, too.

Does anyone have more insight into how the whole locking ranges workflow works? So far I've really only worked with the global locking range.

EDIT: Is --setupLockingRange only for changing the size of a locking range? But it's not actually required to create one? Does --enableLockingRange already do that? But what size would the locking range even be, then? Is there a default size? Or will it just have a size of 0 logical blocks, until it is given a size with --setupLockingRange?

Blacklands commented 1 year ago

I've found #39 and A Practical Guide to Use of Opal Drives.

So if I've understood it correctly, [enable|disable]LockingRange just changes whether a power-cycle will re-lock the respective range, or not. What gets modified are the WriteLockEnabled|ReadLockEnabled bits for the range.

setLockingRange, on the other hand, modifies the other two bits, ReadLocked|WriteLocked. It can lock or unlock a range. If [Write|Read]LockEnabled are set, after a power-cycle the range will be locked again. ([Read|Write]Locked are unset again). EDIT: Actually, it appears that [Read|Write]Locked will still be set, but simply have no effect if [Write|Read]LockEnabled are not also set.

And setupLockingRange only changes the size (in logical blocks) of a range? From the output of --listLockingRanges, it looks like all ranges (except the global range, 0) have size 0 by default, right? (It says that for the global range too, but I assume that doesn't mean anything. The global range simply always occupies all space on the disk that is not being occupied by any other range, or by some of the hard-coded spaces like the Shadow MBR. Which also means the global range can occupy non-consecutive space, it can be split up into multiple "pieces" on the drive level, so to speak.)

So if I wanted to see if a locking range has been set up for use, I could look at the output of listLockingRanges, and if a range (except the global range) has size 0, it isn't set up. Is that correct?


I also wonder what the Locked = [Y|N] flag refers to in the --query output for a drive. Does that always refer to the global locking range? Or does it basically mean "if all ranges have ReadLocked and WriteLocked unset, the drive is considered locked, otherwise if a single range is at least unlocked for reading (and/or writing?), the drive is considered unlocked"? Or something else entirely? When I experimented with it, it seemed like the flag only changes state when the global locking range is locked/unlocked.

EDIT: According to #7 and #72, the flag seems to be only for the global locking range. So if we want to check the state of any other range, we should rather check it in the --listLockingRanges output.