From 62f667faddf4adeca1a3a19e28246b27db8bce41 Mon Sep 17 00:00:00 2001 From: Michal Gawlik Date: Tue, 14 Apr 2020 19:52:02 +0200 Subject: [PATCH] Use new kernel (5.3+) API for setting MBRDone flag alone 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+. --- README.md | 4 +++- sed-opal-unlocker.c | 20 +++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9d26f8d..25238f5 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/sed-opal-unlocker.c b/sed-opal-unlocker.c index 7ed7f97..4e5a452 100644 --- a/sed-opal-unlocker.c +++ b/sed-opal-unlocker.c @@ -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) @@ -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); @@ -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));