Skip to content

Commit

Permalink
Revert "Fix MBRunshadow for newer kernels"
Browse files Browse the repository at this point in the history
This reverts commit a031df7.

sed-opal-unlocker is going to support kernels 5.3+ only. The
MBRunshadowOLD is no longer needed.
  • Loading branch information
dex6 committed Apr 14, 2020
1 parent a031df7 commit 25f5373
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 17 deletions.
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,14 @@ If you are Gentoo Linux user, you will find an ebuild in [my overlay](https://gi
```

Where:
- `<operation>` is one of: lock, unlock, MBRunshadow, MBRunshadowOLD, s3save or comma-separated space-less combination of them (except lock)
- `<operation>` is one of: lock, unlock, MBRunshadow, s3save or comma-separated space-less combination of them (except lock)
- `<disk_path>` is device path, eg. /dev/sda, /dev/nvme0n1, etc.
- `<password_file_path>` is path to file containing the disk password; if password file is encrypted, passphrase for decrypting it is read from stdin.

Operation specifies what the tool should do:
- `lock`: lock the drive. Useful mainly for testing.
- `unlock`: unlock the drive. The main feature of this tool.
- `MBRunshadow`: disable MBR shadow image. Use after unlock when the disk has been configured to shadow MBR (see below).
- `MBRunshadowOLD`: the same as MBRunshadow, but for older kernels (see below).
- `s3save`: store password in the Linux kernel for enabling drive unlock after S3 sleep.

When the disk has been initialized with sedutil-cli without using its `-n` option, the password which is send to the disk is a hash calculated using PKBDF2 algorithm from plain text password and the disk serial for salting. In order to use such password with `sed-opal-unlocker`, all you need to do is to store the hashed password in the password file. Fortunately, there's a Python script which will do this for you.
Expand All @@ -80,12 +79,6 @@ When the last optional argument, [encrypt_password] is provided and set to 1, th

Please also note that the encrypted password file does not store any authentication/verification data. Had the attacker obtained an encrypted passwordfile, he/she still cannot bruteforce it, cause only the disk can tell whether the unlock passphrase is correct or not. Even having access to the disk does not make bruteforcing easier, cause (a) argon2, (b) OPAL disks have limit how many times you may enter wrong password, and then will require a power-cycle to start talking to you again.

### MBRunshadow vs MBRunshadowOLD

Since kernel 5.2 and stable kernels 5.1.6, 5.0.20, 4.19.47 and 4.14.123, a bug in kernel API used by sed-opal-unlocker to switch off MBR shadowing has been fixed. However, the fix goes against the policy of not breaking userspace applications and now sed-opal-unlocker needs to be fixed as well... Cause it's not possible to easily tell whether the kernel is fixed or not, since version 0.3.1 the sed-opal-unlocker has switched to new (fixed) kernel API. However a new operation, MBRunshadowOLD, has been added to still support older (unfixed) kernels. The side effect of using wrong action (MBRunshadow on an old kernel or MBRunshadowOLD on a new kernel) is disabling the MBREnable flag, which means the whole shadowing is deactivated and PBA image is not presented to the host, so the system cannot boot from such device. In order to recover, use correct sed-opal-unlocker operation once or use sedutil-cli --setMBREnable on. See [this kernel commit](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/block/sed-opal.c?id=78bf47353b0041865564deeed257a54f047c2fdc) for more info.

Also, please note that kernel 5.3 is going to have a better API for switching MBRDone flag and I'm already planning to utilize it in the sed-opal-unlocker. Please expect another rework in this area in a near future.

### Bonus: disk initialization notes

The most helpful information source for me was [Self-Encrypting Drives](https://wiki.archlinux.org/index.php/Self-Encrypting_Drives) article on Archlinux wiki. Another source worth looking at is [sedutil wiki](https://github.com/Drive-Trust-Alliance/sedutil/wiki).
Expand Down
14 changes: 5 additions & 9 deletions sed-opal-unlocker.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static int help(const char *banner)
printf("\tsed-opal-unlocker <operation> <disk_path> <password_file_path>\n");
printf("\n");
printf("Where:\n");
printf("\t<operation> is one of: lock, unlock, MBRunshadow, MBRunshadowOLD, s3save\n");
printf("\t<operation> is one of: lock, unlock, MBRunshadow, s3save\n");
printf("\t or comma-separated combination of them (except lock)\n");
printf("\t<disk_path> is device path, ex. /dev/sda, /dev/nvme0n1, etc.\n");
printf("\t<password_file_path> is path to file containing the admin1 password\n");
Expand All @@ -73,9 +73,8 @@ static int help(const char *banner)
#define OP_LOCK (1 << 0)
#define OP_UNLOCK (1 << 1)
#define OP_UNSHADOW (1 << 2)
#define OP_UNSHADOW_OLD (1 << 3)
#define OP_S3SAVE (1 << 4)
#define OP_DECRYPT_PWD (1 << 5)
#define OP_S3SAVE (1 << 3)
#define OP_DECRYPT_PWD (1 << 4)
static int parse_operation(const char *opstring)
{
char buf[1024], *p, *rest;
Expand All @@ -99,8 +98,6 @@ static int parse_operation(const char *opstring)
ret |= OP_S3SAVE;
else if (strcmp(p, "MBRunshadow") == 0)
ret |= OP_UNSHADOW;
else if (strcmp(p, "MBRunshadowOLD") == 0)
ret |= OP_UNSHADOW_OLD;
else if (strcmp(p, "decryptpasswd") == 0)
ret |= OP_DECRYPT_PWD;
else
Expand Down Expand Up @@ -356,15 +353,14 @@ int main(int argc, char* argv[])
}
}
}
if (mode & (OP_UNSHADOW | OP_UNSHADOW_OLD))
if (mode & OP_UNSHADOW)
{
memset(&mbr_data, 0, sizeof(struct opal_mbr_data));

// Set MBRDone = Y
// NOTE: due to kernel API, this also sets MBREnabled = Y... but this should not hurt,
// cause MBRunshadow is expected to be called only when MBREnabled = Y already.
// See README for UNSHADOW vs UNSHADOW_OLD explanation...
mbr_data.enable_disable = (mode & OP_UNSHADOW_OLD) ? 1 : OPAL_MBR_ENABLE;
mbr_data.enable_disable = 1;
// 0 locking range (global range)
mbr_data.key.lr = 0;
// Copy key
Expand Down

0 comments on commit 25f5373

Please sign in to comment.