Skip to content

Commit

Permalink
Use new kernel (5.3+) API for setting MBRDone flag alone
Browse files Browse the repository at this point in the history
In older kernels, the only way to set MBRDone=y was to use
IOC_OPAL_ENABLE_DISABLE_MBR, which sets both MBREnabled and MBRDone
flags to the same value. In newer kernels we have IOC_OPAL_MBR_DONE,
which sets only MBRDone. This is way better (having no side effects),
but means sed-opal-unlocker now requires kernel 5.3+.
  • Loading branch information
dex6 committed Apr 14, 2020
1 parent 25f5373 commit 62f667f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 12 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# sed-opal-unlocker

Micro-utility for unlocking TCG-OPAL encrypted disks, utilizing CONFIG_BLK_SED_OPAL interface introduced in kernel 4.11. Also allows saving password in the running kernel for S3 Sleep support, cause it was a cheap feature to have. Based on Kyle Manna's [opalctl](https://github.com/kylemanna/opalctl) nano-utility.
Micro-utility for unlocking TCG-OPAL encrypted disks, utilizing CONFIG_BLK_SED_OPAL interface introduced in kernel 4.11 (but see [1] below). Also allows saving password in the running kernel for S3 Sleep support, cause it was a cheap feature to have. Based on Kyle Manna's [opalctl](https://github.com/kylemanna/opalctl) nano-utility.

[1] Since 1.0.0, sed-opal-unlocker requires kernel 5.3 or newer, cause it utilizes IOC_OPAL_MBR_DONE interface. If you need to use older kernel, checkout v0.3.1 and read "MBRunshadow vs MBRunshadowOLD" section carefully in its README if you plan to use MBRunshadow.


### Background
Expand Down
20 changes: 9 additions & 11 deletions sed-opal-unlocker.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ int main(int argc, char* argv[])
int passwd_len = 0;
uint8_t passwd[OPAL_KEY_MAX]; // note: maybe not-NULL-terminated
struct opal_lock_unlock lk_unlk;
struct opal_mbr_data mbr_data;
struct opal_mbr_done mbr_done;

// Parse arguments
if (argc < 4)
Expand Down Expand Up @@ -355,23 +355,21 @@ int main(int argc, char* argv[])
}
if (mode & OP_UNSHADOW)
{
memset(&mbr_data, 0, sizeof(struct opal_mbr_data));
memset(&mbr_done, 0, sizeof(struct opal_mbr_done));

// 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.
mbr_data.enable_disable = 1;
mbr_done.done_flag = OPAL_MBR_DONE;
// 0 locking range (global range)
mbr_data.key.lr = 0;
mbr_done.key.lr = 0;
// Copy key
memcpy(mbr_data.key.key, passwd, passwd_len);
memcpy(mbr_done.key.key, passwd, passwd_len);
// Set key size
mbr_data.key.key_len = passwd_len;
mbr_done.key.key_len = passwd_len;

ret = ioctl(fd, IOC_OPAL_ENABLE_DISABLE_MBR, &mbr_data);
ret = ioctl(fd, IOC_OPAL_MBR_DONE, &mbr_done);
if (ret != 0)
{
snprintf(buf, sizeof(buf), "Failed to ioctl(%s, IOC_OPAL_ENABLE_DISABLE_MBR, ...)", target_path);
snprintf(buf, sizeof(buf), "Failed to ioctl(%s, IOC_OPAL_MBR_DONE, ...)", target_path);
if (errno == 0)
errno = EINVAL;
perror(buf);
Expand All @@ -392,7 +390,7 @@ int main(int argc, char* argv[])
cleanup:
close(fd);
exit:
mem_zeroize(&mbr_data, sizeof(mbr_data));
mem_zeroize(&mbr_done, sizeof(mbr_done));
mem_zeroize(&lk_unlk, sizeof(lk_unlk));
mem_zeroize(passwd, sizeof(passwd));
mem_zeroize(buf, sizeof(buf));
Expand Down

0 comments on commit 62f667f

Please sign in to comment.