From 54c65748b5cf2bbc3910b8cfd810aaa6eebe06d6 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 Nov 2017 22:25:22 +0100 Subject: [PATCH 1/6] Add option to use non-ascii passwords This is to allow proper '-h' (no password hashing) usage, where the user might have saved the hash itself, or used a different hashing mechanism altogether, and ends up with 0 bytes or control characters in the resulting string. --- Common/DtaDev.h | 1 + Common/DtaHashPwd.cpp | 48 +++++++++++++++++++++++++++++-------------- Common/DtaHashPwd.h | 4 ++-- Common/DtaOptions.cpp | 7 ++++++- Common/DtaOptions.h | 1 + Common/sedutil.cpp | 2 ++ 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/Common/DtaDev.h b/Common/DtaDev.h index 04096a2a..23bdaabb 100644 --- a/Common/DtaDev.h +++ b/Common/DtaDev.h @@ -294,6 +294,7 @@ class DtaDev { /** return the communications ID to be used for sessions to this device */ virtual uint16_t comID() = 0; bool no_hash_passwords; /** disables hashing of passwords */ + bool hex_passwords; /** converts passwords from hex before using them */ sedutiloutput output_format; /** standard, readable, JSON */ protected: const char * dev; /**< character string representing the device in the OS lexicon */ diff --git a/Common/DtaHashPwd.cpp b/Common/DtaHashPwd.cpp index 19973935..d3b888a4 100644 --- a/Common/DtaHashPwd.cpp +++ b/Common/DtaHashPwd.cpp @@ -32,8 +32,8 @@ extern "C" { } using namespace std; -void DtaHashPassword(vector &hash, char * password, vector salt, - unsigned int iter, uint8_t hashsize) +void DtaHashPassword(vector &hash, const vector& password, + const vector& salt, unsigned int iter, uint8_t hashsize) { LOG(D1) << " Entered DtaHashPassword"; // if the hashsize can be > 255 the token overhead logic needs to be fixed @@ -42,7 +42,7 @@ void DtaHashPassword(vector &hash, char * password, vector sal hash.clear(); // don't hash the devault OPAL password '' - if (0 == strnlen(password, 32)) { + if (0 == password.size()) { goto exit; } hash.reserve(hashsize + 2); // hope this will prevent reallocation @@ -50,7 +50,7 @@ void DtaHashPassword(vector &hash, char * password, vector sal hash.push_back(' '); } - cf_pbkdf2_hmac((uint8_t *)password, strnlen(password, 256), + cf_pbkdf2_hmac(&password[0], password.size(), salt.data(), salt.size(), iter, hash.data(), hash.size(), @@ -67,21 +67,38 @@ void DtaHashPwd(vector &hash, char * password, DtaDev * d) { LOG(D1) << " Entered DtaHashPwd"; char *serNum; + vector decoded_password; + if (d->hex_passwords) + { + for (char* p=password; *p; ++p) + { + uint8_t num1 = (uint8_t)(*p & 0x40 ? (*p & 0xf) + 9 : *p & 0xf); + ++p; + if (*p == 0) + break; + uint8_t num2 = (uint8_t)(*p & 0x40 ? (*p & 0xf) + 9 : *p & 0xf); + decoded_password.push_back(num1 * 16 + num2); + } + } + else + { + decoded_password.assign(password, password + strlen(password)); + } if (d->no_hash_passwords) { - hash.clear(); - for (uint16_t i = 0; i < strnlen(password, 32); i++) - hash.push_back(password[i]); - // add the token overhead - hash.insert(hash.begin(), (uint8_t)hash.size()); - hash.insert(hash.begin(), 0xd0); - LOG(D1) << " Exit DtaHashPwd"; - return; + if (decoded_password.size() > 32) + decoded_password.resize(32); + hash = decoded_password; + // add the token overhead + hash.insert(hash.begin(), (uint8_t)hash.size()); + hash.insert(hash.begin(), 0xd0); + LOG(D1) << " Exit DtaHashPwd"; + return; } serNum = d->getSerialNum(); vector salt(serNum, serNum + 20); // vector salt(DEFAULTSALT); - DtaHashPassword(hash, password, salt); + DtaHashPassword(hash, decoded_password, salt); LOG(D1) << " Exit DtaHashPwd"; // log for hash timing } @@ -109,7 +126,7 @@ int testresult(std::vector &result, const char * expected, size_t len) int Testsedutil(const PBKDF_TestTuple *testSet, unsigned int testSetSize) { int pass = 1; - std::vector hash, seaSalt; + std::vector hash, seaSalt, password; for (unsigned int i = 0; i < testSetSize; i++) { const PBKDF_TestTuple &tuple = testSet[i]; @@ -120,7 +137,8 @@ int Testsedutil(const PBKDF_TestTuple *testSet, unsigned int testSetSize) } printf("Password %s Salt %s Iterations %i Length %i\n", (char *)tuple.Password, (char *) tuple.Salt, tuple.iterations, tuple.hashlen); - DtaHashPassword(hash, (char *) tuple.Password, seaSalt, tuple.iterations, tuple.hashlen); + password.assign(tuple.Password, tuple.Password+strlen(tuple.Password)); + DtaHashPassword(hash, password, seaSalt, tuple.iterations, tuple.hashlen); int fail = (testresult(hash, tuple.hexDerivedKey, tuple.hashlen) == 0); pass = pass & fail; } diff --git a/Common/DtaHashPwd.h b/Common/DtaHashPwd.h index 3815f7c6..2e28497d 100644 --- a/Common/DtaHashPwd.h +++ b/Common/DtaHashPwd.h @@ -41,7 +41,7 @@ void DtaHashPwd(vector &hash, char * password, DtaDev * device); * @param iter number of iterations to be preformed * @param hashsize size of hash to be returned */ -void DtaHashPassword(vector &hash, char * password, vector salt, - unsigned int iter = 75000, uint8_t hashsize = 32); +void DtaHashPassword(vector &hash, const vector &password, + const vector &salt, unsigned int iter = 75000, uint8_t hashsize = 32); /** Test the hshing function using publicly available test cased and report */ int TestPBKDF2(); diff --git a/Common/DtaOptions.cpp b/Common/DtaOptions.cpp index 92227f89..2422f4ee 100644 --- a/Common/DtaOptions.cpp +++ b/Common/DtaOptions.cpp @@ -27,10 +27,11 @@ void usage() printf("a utility to manage self encrypting drives that conform\n"); printf("to the TCG Enterprise, Opal, Opalite and Pyrite SSC specs\n"); printf("General Usage: (see readme for extended commandset)\n"); - printf("sedutil-cli <-v> <-n> \n"); + printf("sedutil-cli <-v> <-n> <-x> \n"); printf("-v (optional) increase verbosity, one to five v's\n"); printf("-n (optional) no password hashing. Passwords will be sent in clear text!\n"); printf("-l (optional) log style output to stderr only\n"); + printf("-x (optional) password inputs are in hex form\n"); printf("actions \n"); printf("--scan \n"); printf(" Scans the devices on the system \n"); @@ -144,6 +145,10 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) opts->output_format = sedutilNormal; outputFormat = sedutilNormal; } + else if (!strcmp("-x", argv[i])) { + baseOptions += 1; + opts->hex_passwords = true; + } else if (!(('-' == argv[i][0]) && ('-' == argv[i][1])) && (0 == opts->action)) { diff --git a/Common/DtaOptions.h b/Common/DtaOptions.h index c012af1d..286b3f8f 100644 --- a/Common/DtaOptions.h +++ b/Common/DtaOptions.h @@ -43,6 +43,7 @@ typedef struct _DTA_OPTIONS { uint8_t lrlength; /** the length in blocks of a lockingrange */ bool no_hash_passwords; /** global parameter, disables hashing of passwords */ + bool hex_passwords; /** global parameter, all incoming passwords are treated as hex-encoded */ sedutiloutput output_format; } DTA_OPTIONS; /** Print a usage message */ diff --git a/Common/sedutil.cpp b/Common/sedutil.cpp index 270709e9..e5edc84f 100644 --- a/Common/sedutil.cpp +++ b/Common/sedutil.cpp @@ -107,6 +107,8 @@ int main(int argc, char * argv[]) // make sure DtaDev::no_hash_passwords is initialized d->no_hash_passwords = opts.no_hash_passwords; + d->hex_passwords = opts.hex_passwords; + d->output_format = opts.output_format; } From 0fce1263c0e2f28fac5cf186e76c17a5b2061b7a Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 Nov 2017 22:51:21 +0100 Subject: [PATCH 2/6] Option to print the password hash Useful for users, who want to use different utilities with their SED drives, and also in combination with "-x -n", meaning "no hash", "hex", so no plaintext passwords are saved to scripts or shell history. --- Common/DtaDev.cpp | 19 +++++++++++++++++++ Common/DtaDev.h | 3 +++ Common/DtaOptions.cpp | 7 +++++++ Common/DtaOptions.h | 1 + Common/sedutil.cpp | 4 ++++ 5 files changed, 34 insertions(+) diff --git a/Common/DtaDev.cpp b/Common/DtaDev.cpp index cd77a716..f6c56eb8 100644 --- a/Common/DtaDev.cpp +++ b/Common/DtaDev.cpp @@ -32,6 +32,7 @@ along with sedutil. If not, see . #include "DtaConstants.h" #include "DtaEndianFixup.h" #include "DtaHexDump.h" +#include "DtaHashPwd.h" using namespace std; @@ -313,6 +314,24 @@ void DtaDev::discovery0() while (cpos < epos); } + +uint8_t DtaDev::printPasswordHash(char * password) +{ + LOG(D1) << "Entering DtaDev::printPasswordHash()"; + vector hash; + DtaHashPwd(hash, password, this); + + /* std::hex overwrites flags; save them, so we do not alter other output later */ + ios_base::fmtflags saved_flags = cout.flags(); + + /* First two bytes are actually the opal header */ + for (size_t i = 2; i < hash.size(); ++i) + cout << hex << setfill('0') << setw(2) << (int)hash[i]; + cout << endl; + cout.flags(saved_flags); + return 0; +} + void DtaDev::puke() { LOG(D1) << "Entering DtaDev::puke()"; diff --git a/Common/DtaDev.h b/Common/DtaDev.h index 23bdaabb..b43bedc5 100644 --- a/Common/DtaDev.h +++ b/Common/DtaDev.h @@ -84,6 +84,9 @@ class DtaDev { */ void discovery0(); + /** Print password hash, computed with this device's serial number + */ + uint8_t printPasswordHash(char * password); /* * virtual methods required in the OS specific * device class diff --git a/Common/DtaOptions.cpp b/Common/DtaOptions.cpp index 2422f4ee..8578f5d0 100644 --- a/Common/DtaOptions.cpp +++ b/Common/DtaOptions.cpp @@ -100,6 +100,9 @@ void usage() printf(" AdminSP->Revert instead of ThisSP->RevertSP\n"); printf("--printDefaultPassword \n"); printf(" print MSID \n"); + printf("--printPasswordHash \n"); + printf(" print the hash of the password \n"); + printf(" as computed by sedutil. Hex-ecoded.\n"); printf("\n"); printf("Examples \n"); printf("sedutil-cli --scan \n"); @@ -520,6 +523,10 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) END_OPTION BEGIN_OPTION(objDump, 5) i += 4; OPTION_IS(device) END_OPTION BEGIN_OPTION(printDefaultPassword, 1) OPTION_IS(device) END_OPTION + BEGIN_OPTION(printPasswordHash, 2) + OPTION_IS(password) + OPTION_IS(device) + END_OPTION BEGIN_OPTION(rawCmd, 7) i += 6; OPTION_IS(device) END_OPTION else { LOG(E) << "Invalid command line argument " << argv[i]; diff --git a/Common/DtaOptions.h b/Common/DtaOptions.h index 286b3f8f..715b75b8 100644 --- a/Common/DtaOptions.h +++ b/Common/DtaOptions.h @@ -96,6 +96,7 @@ typedef enum _sedutiloption { validatePBKDF2, objDump, printDefaultPassword, + printPasswordHash, rawCmd, } sedutiloption; diff --git a/Common/sedutil.cpp b/Common/sedutil.cpp index e5edc84f..cd24c735 100644 --- a/Common/sedutil.cpp +++ b/Common/sedutil.cpp @@ -275,6 +275,10 @@ int main(int argc, char * argv[]) LOG(D) << "print default password"; return d->printDefaultPassword(); break; + case sedutiloption::printPasswordHash: + LOG(D) << "print password hash"; + return d->printPasswordHash(argv[opts.password]); + break; case sedutiloption::rawCmd: LOG(D) << "Performing cmdDump "; return d->rawCmd(argv[argc - 7], argv[argc - 6], argv[argc - 5], argv[argc - 4], argv[argc - 3], argv[argc - 2]); From ce324c8f8eacdc9349f3829f38936e326c7808e2 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 19 Nov 2017 00:44:28 +0100 Subject: [PATCH 3/6] Add S3 sleep support for Linux The new command is --prepareForS3Sleep, and it should be called every new boot, as it stores the drive key (password hash) in kernel memory. --- Common/DtaDev.cpp | 6 +++++ Common/DtaDev.h | 5 +++++ Common/DtaOptions.cpp | 24 ++++++++++++++++++++ Common/DtaOptions.h | 1 + Common/sedutil.cpp | 4 ++++ Makefile.am | 6 +++-- linux/DtaDevLinuxDrive.cpp | 46 ++++++++++++++++++++++++++++++++++++++ linux/DtaDevLinuxDrive.h | 5 +++++ linux/DtaDevLinuxNvme.h | 1 - linux/DtaDevLinuxSata.h | 1 - linux/DtaDevOS.cpp | 33 +++++++++++++++++++++++++++ linux/DtaDevOS.h | 2 ++ 12 files changed, 130 insertions(+), 4 deletions(-) create mode 100755 linux/DtaDevLinuxDrive.cpp diff --git a/Common/DtaDev.cpp b/Common/DtaDev.cpp index f6c56eb8..50e455dc 100644 --- a/Common/DtaDev.cpp +++ b/Common/DtaDev.cpp @@ -506,3 +506,9 @@ void DtaDev::puke() if (disk_info.Unknown) cout << "**** " << (uint16_t)disk_info.Unknown << " **** Unknown function codes IGNORED " << std::endl; } + +uint8_t DtaDev::prepareForS3Sleep(uint8_t lockingrange, char* password) +{ + LOG(E) << "S3 sleep not supported on this platform"; + return 1; +} diff --git a/Common/DtaDev.h b/Common/DtaDev.h index b43bedc5..3dd15263 100644 --- a/Common/DtaDev.h +++ b/Common/DtaDev.h @@ -262,6 +262,11 @@ class DtaDev { * @param password Password of administrative authority for locking range */ virtual uint8_t eraseLockingRange(uint8_t lockingrange, char * password) = 0; + /** Optionally implemented s3 sleep support. + * On Linux, it saves the password to the kernel to use on resume. + * @param password the password to save to the kernel + */ + virtual uint8_t prepareForS3Sleep(uint8_t lockingrange, char* password); /** Dumps an object for diagnostic purposes * @param sp index into the OPALUID table for the SP the object is in * @param auth the authority to use for the dump diff --git a/Common/DtaOptions.cpp b/Common/DtaOptions.cpp index 8578f5d0..dfb41ad3 100644 --- a/Common/DtaOptions.cpp +++ b/Common/DtaOptions.cpp @@ -103,6 +103,9 @@ void usage() printf("--printPasswordHash \n"); printf(" print the hash of the password \n"); printf(" as computed by sedutil. Hex-ecoded.\n"); + printf("--prepareForS3Sleep <0...n> \n"); + printf(" Automatically unlock range after S3 resume\n"); + printf(" This command will save the password to kernel memory\n"); printf("\n"); printf("Examples \n"); printf("sedutil-cli --scan \n"); @@ -527,6 +530,27 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) OPTION_IS(password) OPTION_IS(device) END_OPTION + BEGIN_OPTION(prepareForS3Sleep, 3) + TESTARG(0, lockingrange, 0) + TESTARG(1, lockingrange, 1) + TESTARG(2, lockingrange, 2) + TESTARG(3, lockingrange, 3) + TESTARG(4, lockingrange, 4) + TESTARG(5, lockingrange, 5) + TESTARG(6, lockingrange, 6) + TESTARG(7, lockingrange, 7) + TESTARG(8, lockingrange, 8) + TESTARG(9, lockingrange, 9) + TESTARG(10, lockingrange, 10) + TESTARG(11, lockingrange, 11) + TESTARG(12, lockingrange, 12) + TESTARG(13, lockingrange, 13) + TESTARG(14, lockingrange, 14) + TESTARG(15, lockingrange, 15) + TESTFAIL("Invalid Locking Range (0-15)") + OPTION_IS(password) + OPTION_IS(device) + END_OPTION BEGIN_OPTION(rawCmd, 7) i += 6; OPTION_IS(device) END_OPTION else { LOG(E) << "Invalid command line argument " << argv[i]; diff --git a/Common/DtaOptions.h b/Common/DtaOptions.h index 715b75b8..669eef8c 100644 --- a/Common/DtaOptions.h +++ b/Common/DtaOptions.h @@ -97,6 +97,7 @@ typedef enum _sedutiloption { objDump, printDefaultPassword, printPasswordHash, + prepareForS3Sleep, rawCmd, } sedutiloption; diff --git a/Common/sedutil.cpp b/Common/sedutil.cpp index cd24c735..2c816d10 100644 --- a/Common/sedutil.cpp +++ b/Common/sedutil.cpp @@ -279,6 +279,10 @@ int main(int argc, char * argv[]) LOG(D) << "print password hash"; return d->printPasswordHash(argv[opts.password]); break; + case sedutiloption::prepareForS3Sleep: + LOG(D) << "Preparing for S3 sleep " << (uint16_t) opts.lockingrange; + return d->prepareForS3Sleep(opts.lockingrange, argv[opts.password]); + break; case sedutiloption::rawCmd: LOG(D) << "Performing cmdDump "; return d->rawCmd(argv[argc - 7], argv[argc - 6], argv[argc - 5], argv[argc - 4], argv[argc - 3], argv[argc - 2]); diff --git a/Makefile.am b/Makefile.am index bd08c382..0a7a9180 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,7 +29,8 @@ sedutil_cli_SOURCES = linux/Version.h Common/sedutil.cpp Common/DtaOptions.cpp C linux/DtaDevLinuxNvme.cpp linux/DtaDevLinuxNvme.h \ linux/DtaDevLinuxSata.cpp linux/DtaDevLinuxSata.h \ linux/DtaDevOS.cpp linux/DtaDevOS.h \ - linux/DtaDevLinuxDrive.h linux/os.h \ + linux/DtaDevLinuxDrive.cpp linux/DtaDevLinuxDrive.h \ + linux/os.h \ $(SEDUTIL_COMMON_CODE) CLEANFILES = linux/Version.h BUILT_SOURCES = linux/Version.h @@ -40,7 +41,8 @@ linuxpba_SOURCES = LinuxPBA/LinuxPBA.cpp LinuxPBA/GetPassPhrase.cpp LinuxPBA/Unl linux/DtaDevLinuxNvme.cpp linux/DtaDevLinuxNvme.h \ linux/DtaDevLinuxSata.cpp linux/DtaDevLinuxSata.h \ linux/DtaDevOS.cpp linux/DtaDevOS.h \ - linux/DtaDevLinuxDrive.h linux/os.h \ + linux/DtaDevLinuxDrive.cpp linux/DtaDevLinuxDrive.h \ + linux/os.h \ \ $(SEDUTIL_COMMON_CODE) EXTRA_DIST = linux/GitVersion.sh linux/PSIDRevert_LINUX.txt linux/TestSuite.sh README.md docs/sedutil-cli.8 diff --git a/linux/DtaDevLinuxDrive.cpp b/linux/DtaDevLinuxDrive.cpp new file mode 100755 index 00000000..d04606a9 --- /dev/null +++ b/linux/DtaDevLinuxDrive.cpp @@ -0,0 +1,46 @@ +/* C:B************************************************************************** +Copyright 2017, Alex Badics + +This file is part of sedutil. + +sedutil is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +sedutil is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with sedutil. If not, see . + + * C:E********************************************************************** */ +#include "os.h" +#include +#include +#include "DtaDevLinuxDrive.h" + +using namespace std; + +uint8_t DtaDevLinuxDrive::prepareForS3Sleep(uint8_t lockingrange, const vector &password_hash) +{ + LOG(D1) << "Entering DtaDevLinuxDrive::prepareForS3Sleep"; + + opal_lock_unlock opal_ioctl_data={}; + opal_ioctl_data.l_state = OPAL_RW; + opal_ioctl_data.session.who = OPAL_ADMIN1; + opal_ioctl_data.session.opal_key.lr = 0; + + size_t hash_len=min(password_hash.size(), sizeof(opal_ioctl_data.session.opal_key.key)); + LOG(D2) << "Setting a hash of length" << hash_len; + + memcpy(opal_ioctl_data.session.opal_key.key, &password_hash[0], hash_len); + opal_ioctl_data.session.opal_key.key_len = hash_len; + + int err = ioctl(fd, IOC_OPAL_SAVE, &opal_ioctl_data); + if (err < 0) + return errno; + return 0; +} diff --git a/linux/DtaDevLinuxDrive.h b/linux/DtaDevLinuxDrive.h index d2022a16..39d1951f 100755 --- a/linux/DtaDevLinuxDrive.h +++ b/linux/DtaDevLinuxDrive.h @@ -18,8 +18,10 @@ along with sedutil. If not, see . * C:E********************************************************************** */ #pragma once +#include #include "DtaStructures.h" +using namespace std; /** virtual implementation for a disk interface-generic disk drive */ class DtaDevLinuxDrive { @@ -45,4 +47,7 @@ class DtaDevLinuxDrive { void * buffer, uint32_t bufferlen) = 0; /** Routine to send an identify to the device */ virtual void identify(OPAL_DiskInfo& disk_info) = 0; + /** Save the password hash to the kernel for S3 sleep wakeup */ + uint8_t prepareForS3Sleep(uint8_t lockingrange, const vector &password_hash); + int fd; /**< Linux handle for the device */ }; diff --git a/linux/DtaDevLinuxNvme.h b/linux/DtaDevLinuxNvme.h index 3ea6874d..b305a88f 100755 --- a/linux/DtaDevLinuxNvme.h +++ b/linux/DtaDevLinuxNvme.h @@ -59,5 +59,4 @@ class DtaDevLinuxNvme: public DtaDevLinuxDrive{ void * buffer, uint32_t bufferlen); /** NVMe specific routine to send an identify to the device */ void identify(OPAL_DiskInfo& disk_info); - int fd; /**< Linux handle for the device */ }; diff --git a/linux/DtaDevLinuxSata.h b/linux/DtaDevLinuxSata.h index 14b7e12a..6e19b44d 100755 --- a/linux/DtaDevLinuxSata.h +++ b/linux/DtaDevLinuxSata.h @@ -55,6 +55,5 @@ class DtaDevLinuxSata: public DtaDevLinuxDrive { void * buffer, uint32_t bufferlen); /** Linux specific routine to send an ATA identify to the device */ void identify_SAS(OPAL_DiskInfo *disk_info); - int fd; /**< Linux handle for the device */ int isSAS; /* The device is sas */ }; diff --git a/linux/DtaDevOS.cpp b/linux/DtaDevOS.cpp index e1db38c5..710812ca 100644 --- a/linux/DtaDevOS.cpp +++ b/linux/DtaDevOS.cpp @@ -38,6 +38,9 @@ along with sedutil. If not, see . #include "DtaDevLinuxSata.h" #include "DtaDevLinuxNvme.h" #include "DtaDevGeneric.h" +#include "DtaHashPwd.h" +#include "DtaSession.h" +#include "DtaDevOpal.h" using namespace std; @@ -167,6 +170,36 @@ int DtaDevOS::diskScan() return 0; } +uint8_t DtaDevOS::prepareForS3Sleep(uint8_t lockingrange, char* password) +{ + LOG(D1) << "Entering DtaDevOS::prepareForS3Sleep "; + LOG(D2) << "Starting testing of password "; + session = new DtaSession(this); + if (NULL == session) { + LOG(E) << "Unable to create session object "; + return DTAERROR_OBJECT_CREATE_FAILED; + } + int err; + if ((err = session->start(OPAL_UID::OPAL_LOCKINGSP_UID, password, OPAL_UID::OPAL_ADMIN1_UID)) != 0) { + delete session; + LOG(E) << "Unable to authenticate with the given password"; + return err; + } + delete session; + LOG(D2) << "Test successful, saving it to kernel "; + vector hash; + DtaHashPwd(hash, password, this); + hash.erase(hash.begin(), hash.begin()+2); + + err = drive->prepareForS3Sleep(0, hash); + if (err) + { + LOG(E) << "Error saving the password to the kernel errno = " << errno; + return errno; + } + return 0; +} + /** Close the device reference so this object can be delete. */ DtaDevOS::~DtaDevOS() { diff --git a/linux/DtaDevOS.h b/linux/DtaDevOS.h index beeacb38..fc3705fc 100644 --- a/linux/DtaDevOS.h +++ b/linux/DtaDevOS.h @@ -49,6 +49,8 @@ class DtaDevOS : public DtaDev { void * buffer, uint32_t bufferlen); /** A static class to scan for supported drives */ static int diskScan(); + /** Save device key to kernel for S3 sleep resume */ + uint8_t prepareForS3Sleep(uint8_t lockingrange, char* password); protected: /** OS specific command to Wait for specified number of milliseconds * @param ms number of milliseconds to wait From f57448690aba59b740ed7b2653d6a2a034e020ab Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sun, 2 Jun 2019 08:24:52 +0200 Subject: [PATCH 4/6] prepareForS3Sleep: use locking range Untested, but it seems odd to use 0 when it's passed in from the command line. --- linux/DtaDevLinuxDrive.cpp | 2 +- linux/DtaDevOS.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/DtaDevLinuxDrive.cpp b/linux/DtaDevLinuxDrive.cpp index d04606a9..dda46428 100755 --- a/linux/DtaDevLinuxDrive.cpp +++ b/linux/DtaDevLinuxDrive.cpp @@ -31,7 +31,7 @@ uint8_t DtaDevLinuxDrive::prepareForS3Sleep(uint8_t lockingrange, const vectorprepareForS3Sleep(0, hash); + err = drive->prepareForS3Sleep(lockingrange, hash); if (err) { LOG(E) << "Error saving the password to the kernel errno = " << errno; From 535bb39a66015f82970283e64d4c02b098cea6cc Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Sun, 2 Jun 2019 14:25:49 +0200 Subject: [PATCH 5/6] Fix build of pba image - add define to disable S3 sleep support in pba build --- images/buildroot/packages/sedutil/sedutil.mk | 4 +++- linux/DtaDevLinuxDrive.cpp | 9 ++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/images/buildroot/packages/sedutil/sedutil.mk b/images/buildroot/packages/sedutil/sedutil.mk index 38edfbc0..00172b21 100644 --- a/images/buildroot/packages/sedutil/sedutil.mk +++ b/images/buildroot/packages/sedutil/sedutil.mk @@ -17,9 +17,11 @@ define SEDUTIL_POST_EXTRACT_ACTIONS sed -i '/^CLEANFILES/d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.am sed -i '/^BUILT_SOURCES/d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.am sed -i '/^linux\/Version/,3 d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.am +sed -i 's/^AM_CXXFLAGS.*/\0 -DPBA_BUILD/' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.am sed -i '/^BUILT_SOURCES/d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.in sed -i '/^CLEANFILES/d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.in sed -i '/^linux\/Version/,3 d' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.in +sed -i 's/^AM_CXXFLAGS.*/\0 -DPBA_BUILD/' $(BUILD_DIR)/sedutil-$(SEDUTIL_VERSION)/Makefile.in endef SEDUTIL_POST_EXTRACT_HOOKS += SEDUTIL_POST_EXTRACT_ACTIONS -$(eval $(autotools-package)) \ No newline at end of file +$(eval $(autotools-package)) diff --git a/linux/DtaDevLinuxDrive.cpp b/linux/DtaDevLinuxDrive.cpp index dda46428..39cfab20 100755 --- a/linux/DtaDevLinuxDrive.cpp +++ b/linux/DtaDevLinuxDrive.cpp @@ -19,8 +19,10 @@ along with sedutil. If not, see . * C:E********************************************************************** */ #include "os.h" #include -#include #include "DtaDevLinuxDrive.h" +#ifndef PBA_BUILD +#include +#endif using namespace std; @@ -28,6 +30,10 @@ uint8_t DtaDevLinuxDrive::prepareForS3Sleep(uint8_t lockingrange, const vector Date: Sun, 2 Jun 2019 16:47:33 +0200 Subject: [PATCH 6/6] PBA: Fix uninitialized variable breaking unlocking --- LinuxPBA/UnlockSEDs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/LinuxPBA/UnlockSEDs.cpp b/LinuxPBA/UnlockSEDs.cpp index 4f42e577..076bf967 100644 --- a/LinuxPBA/UnlockSEDs.cpp +++ b/LinuxPBA/UnlockSEDs.cpp @@ -88,6 +88,7 @@ uint8_t UnlockSEDs(char * password) { d = new DtaDevOpal1(devref); delete tempDev; d->no_hash_passwords = false; + d->hex_passwords = false; failed = 0; if (d->Locked()) { if (d->MBREnabled()) {