| From fc3c2d35a98de84b18b7d6a11f65070147b74024 Mon Sep 17 00:00:00 2001 |
| From: Howard McLauchlan <hmclauchlan@fb.com> |
| Date: Tue, 16 Aug 2022 22:11:04 -0700 |
| Subject: [PATCH 2/3] Add securemode/password-setting |
| |
| *BASICALLY CLEANED UP VERSION OF https://github.com/Drive-Trust-Alliance/sedutil/pull/271* |
| |
| This commit does what the linked PR says, and also fixes a few bugs in |
| that original PR. I'm not sure what the right way to give credit is and |
| it was very painful to resurrect CVE's original patches and roll my own |
| on top, so the disclaimer here is that it's like 95% his code :). |
| |
| A few notable things: |
| * We don't need to modify the makefiles, since we split that out in the |
| prior commit. |
| * We fixed his original makefile, which didn't quite work: that change |
| is folded naturally into prior commit. |
| * The generated makefiles don't need to change, because since CVE's |
| original patchset, GetPassPhrase.o was introduced organically to the |
| codebase, and ergo the makefiles. |
| |
| The most interesting thing here is we allow hashing to be forced off by |
| `-n` even during secure mode. |
| |
| The key issue we ran into was that if a drive is originally set with no |
| hashing, then hash'd invocations in the future will fail(obviously). As |
| implemented, CVE's original patches will silently debug output, and then |
| turn on hashing without telling the user. |
| |
| Not a domain expert in why hashing is necessary here, but in either |
| case, I think we should support the case where a password was originally |
| set without hashing, by allowing hashing to be turned off _if_ specified |
| explicitly. |
| |
| We also do some sneaky business by ensuring -n is evaluated after -s, so |
| -n will always override -s, if provided. |
| |
| Signed-off-by: Howard McLauchlan <hmclauchlan@fb.com> |
| --- |
| Common/DtaDev.h | 16 +++-- |
| Common/DtaDevEnterprise.cpp | 30 ++++++--- |
| Common/DtaDevEnterprise.h | 16 +++-- |
| Common/DtaDevGeneric.cpp | 12 ++-- |
| Common/DtaDevGeneric.h | 17 +++-- |
| Common/DtaDevOpal.cpp | 128 ++++++++++++++++++++++++++++-------- |
| Common/DtaDevOpal.h | 26 ++++++-- |
| Common/DtaOptions.cpp | 112 ++++++++++++++++++------------- |
| Common/DtaOptions.h | 36 +++++++--- |
| Common/sedutil.cpp | 81 ++++++++++++----------- |
| linux/os.h | 2 + |
| 11 files changed, 319 insertions(+), 157 deletions(-) |
| |
| diff --git a/Common/DtaDev.h b/Common/DtaDev.h |
| index 473f7bd..c73c179 100644 |
| --- a/Common/DtaDev.h |
| +++ b/Common/DtaDev.h |
| @@ -111,8 +111,9 @@ public: |
| /** User command to prepare the device for management by sedutil. |
| * Specific to the SSC that the device supports |
| * @param password the password that is to be assigned to the SSC master entities |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - virtual uint8_t initialSetup(char * password) = 0; |
| + virtual uint8_t initialSetup(char * password, bool securemode = false) = 0; |
| /** User command to prepare the drive for Single User Mode and rekey a SUM locking range. |
| * @param lockingrange locking range number to enable |
| * @param start LBA to start locking range |
| @@ -120,28 +121,30 @@ public: |
| * @param Admin1Password admin1 password for TPer |
| * @param password User password to set for locking range |
| */ |
| - virtual uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password) = 0; |
| + virtual uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode = false) = 0; |
| /** Set the SID password. |
| * Requires special handling because password is not always hashed. |
| * @param oldpassword current SID password |
| * @param newpassword value password is to be changed to |
| * @param hasholdpwd is the old password to be hashed before being added to the bytestream |
| * @param hashnewpwd is the new password to be hashed before being added to the bytestream |
| + * @param securemode is the new password should be interactively asked |
| */ |
| virtual uint8_t setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) = 0; |
| + uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1, bool securemode = false) = 0; |
| /** Set the password of a locking SP user. |
| * @param password current password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password shoulb be interactively asked |
| */ |
| - virtual uint8_t setPassword(char * password, char * userid, char * newpassword) = 0; |
| + virtual uint8_t setPassword(char * password, char * userid, char * newpassword, bool securemode = false) = 0; |
| /** Set the password of a locking SP user in Single User Mode. |
| * @param password current user password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| */ |
| - virtual uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword) = 0; |
| + virtual uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode = false) = 0; |
| /** Loads a disk image file to the shadow MBR table. |
| * @param password the password for the administrative authority with access to the table |
| * @param filename the filename of the disk image |
| @@ -230,8 +233,9 @@ public: |
| virtual uint8_t eraseLockingRange_SUM(uint8_t lockingrange, char * password) = 0; |
| /** Change the SID password from it's MSID default |
| * @param newpassword new password for SID and locking SP admins |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - virtual uint8_t takeOwnership(char * newpassword) = 0; |
| + virtual uint8_t takeOwnership(char * newpassword, bool securemode = false) = 0; |
| /** Reset the Locking SP to its factory default condition |
| * ERASES ALL DATA! |
| * @param password of Administrative user |
| diff --git a/Common/DtaDevEnterprise.cpp b/Common/DtaDevEnterprise.cpp |
| index ae649ec..ba2e97a 100644 |
| --- a/Common/DtaDevEnterprise.cpp |
| +++ b/Common/DtaDevEnterprise.cpp |
| @@ -171,12 +171,12 @@ DtaDevEnterprise::DtaDevEnterprise(const char * devref) |
| DtaDevEnterprise::~DtaDevEnterprise() |
| { |
| } |
| -uint8_t DtaDevEnterprise::initialSetup(char * password) |
| +uint8_t DtaDevEnterprise::initialSetup(char * password, bool securemode) |
| { |
| LOG(D1) << "Entering initialSetup()"; |
| uint8_t lastRC; |
| |
| - if ((lastRC = takeOwnership(password)) != 0) { |
| + if ((lastRC = takeOwnership(password, securemode)) != 0) { |
| LOG(E) << "Initial setup failed - unable to take ownership"; |
| return lastRC; |
| } |
| @@ -196,7 +196,7 @@ uint8_t DtaDevEnterprise::initialSetup(char * password) |
| LOG(D1) << "Exiting initialSetup()"; |
| return 0; |
| } |
| -uint8_t DtaDevEnterprise::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password) |
| +uint8_t DtaDevEnterprise::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevEnterprise::setup_SUM"; |
| LOG(I) << "setup_SUM not supported on DtaDevEnterprise"; |
| @@ -377,13 +377,18 @@ uint8_t DtaDevEnterprise::revertLockingSP(char * password, uint8_t keep) |
| LOG(D1) << "Exiting DtaDevEnterprise::revertLockingSP()"; |
| return 0; |
| } |
| -uint8_t DtaDevEnterprise::setPassword(char * password, char * userid, char * newpassword) |
| +uint8_t DtaDevEnterprise::setPassword(char * password, char * userid, char * newpassword, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevEnterprise::setPassword" ; |
| - uint8_t lastRC; |
| + uint8_t lastRC = 0; |
| string defaultPassword; |
| char *pwd = password, *newpwd = newpassword; |
| |
| + if (securemode) { |
| + LOG(I) << "setSIDPassword in secure mode in the Enterprise SSC is not supported"; |
| + return lastRC; |
| + } |
| + |
| if (11 > strnlen(userid, 15)) { |
| LOG(E) << "Invalid Userid " << userid; |
| return DTAERROR_INVALID_PARAMETER; |
| @@ -463,7 +468,7 @@ uint8_t DtaDevEnterprise::setPassword(char * password, char * userid, char * new |
| LOG(D1) << "Exiting DtaDevEnterprise::setPassword()"; |
| return 0; |
| } |
| -uint8_t DtaDevEnterprise::setNewPassword_SUM(char * password, char * userid, char * newpassword) |
| +uint8_t DtaDevEnterprise::setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevEnterprise::setNewPassword_SUM()"; |
| LOG(I) << "setNewPassword_SUM is not in the Enterprise SSC and not supported"; |
| @@ -1022,7 +1027,7 @@ uint8_t DtaDevEnterprise::eraseLockingRange_SUM(uint8_t lockingrange, char * pas |
| LOG(D1) << "Exiting DtaDevEnterprise::eraseLockingRange_SUM()"; |
| return DTAERROR_INVALID_PARAMETER; |
| } |
| -uint8_t DtaDevEnterprise::takeOwnership(char * newpassword) |
| +uint8_t DtaDevEnterprise::takeOwnership(char * newpassword, bool securemode) |
| { |
| string defaultPassword; |
| uint8_t lastRC; |
| @@ -1033,7 +1038,7 @@ uint8_t DtaDevEnterprise::takeOwnership(char * newpassword) |
| return lastRC; |
| } |
| defaultPassword = response.getString(5); |
| - if ((lastRC = setSIDPassword((char *)defaultPassword.c_str(), newpassword, 0)) != 0) { |
| + if ((lastRC = setSIDPassword((char *)defaultPassword.c_str(), newpassword, 0, 1, securemode)) != 0) { |
| LOG(E) << "takeOwnership failed unable to set new SID password"; |
| return lastRC; |
| } |
| @@ -1270,10 +1275,15 @@ uint8_t DtaDevEnterprise::printDefaultPassword() |
| return 0; |
| } |
| uint8_t DtaDevEnterprise::setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd, uint8_t hashnewpwd) |
| + uint8_t hasholdpwd, uint8_t hashnewpwd, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevEnterprise::setSIDPassword()"; |
| - uint8_t lastRC; |
| + uint8_t lastRC = 0; |
| + |
| + if (securemode) { |
| + LOG(I) << "setSIDPassword in the Enterprise SSC is not supported"; |
| + return lastRC; |
| + } |
| |
| vector<uint8_t> user; |
| set8(user, OPALUID[OPAL_SID_UID]); |
| diff --git a/Common/DtaDevEnterprise.h b/Common/DtaDevEnterprise.h |
| index 5350da5..4a6d2e2 100644 |
| --- a/Common/DtaDevEnterprise.h |
| +++ b/Common/DtaDevEnterprise.h |
| @@ -57,8 +57,9 @@ public: |
| uint16_t comID(); |
| /** Change the SID password from it's MSID default |
| * @param newpassword new password for SID |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t takeOwnership(char * newpassword); |
| + uint8_t takeOwnership(char * newpassword, bool securemode = false); |
| /** Change the passwords for the enabled Bandmasters and the Erasemaster |
| * from the MSID default. |
| * @param defaultPassword the MSID password |
| @@ -80,9 +81,10 @@ public: |
| * @param newpassword value password is to be changed to |
| * @param hasholdpwd is the old password to be hashed before being added to the bytestream |
| * @param hashnewpwd is the new password to be hashed before being added to the bytestream |
| + * @param securemode is the new password should be interactively asked |
| */ |
| uint8_t setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1); |
| + uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1, bool securemode = false); |
| /** set a single column in an object table |
| * @param table the UID of the table |
| * @param name the column name to be set |
| @@ -124,10 +126,11 @@ public: |
| * @param password current password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setPassword(char * password, char * userid, char * newpassword); |
| + uint8_t setPassword(char * password, char * userid, char * newpassword, bool securemode = false); |
| /** dummy code not implemented in the enterprise SSC*/ |
| - uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword); |
| + uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode = false); |
| uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate, |
| char * password); |
| /** dummy code not implemented in the enterprise SSC*/ |
| @@ -180,10 +183,11 @@ public: |
| /** User command to prepare the device for management by sedutil. |
| * Specific to the SSC that the device supports |
| * @param password the password that is to be assigned to the SSC master entities |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t initialSetup(char * password); |
| + uint8_t initialSetup(char * password, bool securemode = false); |
| /** dummy code not implemented in the enterprise SSC*/ |
| - uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password); |
| + uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode = false); |
| /** Displays the identify and discovery 0 information */ |
| void puke(); |
| /** Dumps an object for diagnostic purposes |
| diff --git a/Common/DtaDevGeneric.cpp b/Common/DtaDevGeneric.cpp |
| index 6f5d57c..8e1bdc9 100644 |
| --- a/Common/DtaDevGeneric.cpp |
| +++ b/Common/DtaDevGeneric.cpp |
| @@ -62,13 +62,13 @@ DtaDevGeneric::~DtaDevGeneric() |
| void DtaDevGeneric::init(const char * devref) |
| { |
| } |
| -uint8NOCODE(initialSetup, char *password) |
| +uint8NOCODE(initialSetup, char *password, bool securemode) |
| uint8NOCODE(configureLockingRange,uint8_t lockingrange, |
| uint8_t enabled, char * password) |
| uint8NOCODE(revertLockingSP,char * password, uint8_t keep) |
| -uint8NOCODE(setup_SUM, uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password) |
| -uint8NOCODE(setPassword,char * password, char * userid, char * newpassword) |
| -uint8NOCODE(setNewPassword_SUM,char * password, char * userid, char * newpassword) |
| +uint8NOCODE(setup_SUM, uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode) |
| +uint8NOCODE(setPassword,char * password, char * userid, char * newpassword, bool securemode) |
| +uint8NOCODE(setNewPassword_SUM,char * password, char * userid, char * newpassword, bool securemode) |
| uint8NOCODE(setMBREnable,uint8_t mbrstate, char * Admin1Password) |
| uint8NOCODE(setMBRDone,uint8_t mbrstate, char * Admin1Password) |
| uint8NOCODE(setLockingRange,uint8_t lockingrange, uint8_t lockingstate, |
| @@ -90,9 +90,9 @@ uint8NOCODE(loadPBA,char * password, char * filename) |
| uint8NOCODE(activateLockingSP,char * password) |
| uint8NOCODE(activateLockingSP_SUM,uint8_t lockingrange, char * password) |
| uint8NOCODE(eraseLockingRange_SUM, uint8_t lockingrange, char * password) |
| -uint8NOCODE(takeOwnership, char * newpassword) |
| +uint8NOCODE(takeOwnership, char * newpassword, bool securemode) |
| uint8NOCODE(setSIDPassword,char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd, uint8_t hashnewpwd) |
| + uint8_t hasholdpwd, uint8_t hashnewpwd, bool securemode) |
| uint16_t DtaDevGeneric::comID() |
| { |
| LOG(E) << "Generic Device class does not support function " << "comID" << std::endl; |
| diff --git a/Common/DtaDevGeneric.h b/Common/DtaDevGeneric.h |
| index 9f5f975..0772878 100644 |
| --- a/Common/DtaDevGeneric.h |
| +++ b/Common/DtaDevGeneric.h |
| @@ -56,36 +56,40 @@ public: |
| * Specific to the SSC that the device supports |
| * @param password the password that is to be assigned to the SSC master entities |
| */ |
| - uint8_t initialSetup(char * password) ; |
| + uint8_t initialSetup(char * password, bool securemode) ; |
| /** User command to prepare the drive for Single User Mode and rekey a SUM locking range. |
| * @param lockingrange locking range number to enable |
| * @param start LBA to start locking range |
| * @param length length (in blocks) for locking range |
| * @param Admin1Password admin1 password for TPer |
| * @param password User password to set for locking range |
| + * @param securemode is the new password shoulb be interactively asked |
| */ |
| - uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password); |
| + uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode = false); |
| /** Set the SID password. |
| * Requires special handling because password is not always hashed. |
| * @param oldpassword current SID password |
| * @param newpassword value password is to be changed to |
| * @param hasholdpwd is the old password to be hashed before being added to the bytestream |
| * @param hashnewpwd is the new password to be hashed before being added to the bytestream |
| + * @param securemode is the new password shoulb be interactively asked |
| */ |
| uint8_t setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) ; |
| + uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1, bool securemode = false) ; |
| /** Set the password of a locking SP user. |
| * @param password current password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setPassword(char * password, char * userid, char * newpassword) ; |
| + uint8_t setPassword(char * password, char * userid, char * newpassword, bool securemode = false) ; |
| /** Set the password of a locking SP user in Single User Mode. |
| * @param password current user password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword) ; |
| + uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode = false) ; |
| /** Loads a disk image file to the shadow MBR table. |
| * @param password the password for the administrative authority with access to the table |
| * @param filename the filename of the disk image |
| @@ -174,8 +178,9 @@ public: |
| uint8_t eraseLockingRange_SUM(uint8_t lockingrange, char * password); |
| /** Change the SID password from it's MSID default |
| * @param newpassword new password for SID and locking SP admins |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t takeOwnership(char * newpassword) ; |
| + uint8_t takeOwnership(char * newpassword, bool securemode = false) ; |
| /** Reset the Locking SP to its factory default condition |
| * ERASES ALL DATA! |
| * @param password of Administrative user |
| diff --git a/Common/DtaDevOpal.cpp b/Common/DtaDevOpal.cpp |
| index 1cb5701..0f6ccc7 100644 |
| --- a/Common/DtaDevOpal.cpp |
| +++ b/Common/DtaDevOpal.cpp |
| @@ -50,31 +50,43 @@ void DtaDevOpal::init(const char * devref) |
| if((lastRC = properties()) != 0) { LOG(E) << "Properties exchange failed";} |
| } |
| |
| -uint8_t DtaDevOpal::initialSetup(char * password) |
| +uint8_t DtaDevOpal::initialSetup(char * password, bool securemode) |
| { |
| LOG(D1) << "Entering initialSetup()"; |
| + std::string newpwd; |
| uint8_t lastRC; |
| - if ((lastRC = takeOwnership(password)) != 0) { |
| + |
| +#ifdef __linux__ |
| + if (securemode) { |
| + if (askNewPassword(newpwd, true) != OPALSTATUSCODE::SUCCESS) { |
| + LOG(E) << "Wrong password confirmation. Failure of password update."; |
| + lastRC = OPALSTATUSCODE::FAIL; |
| + return lastRC; |
| + } |
| + } |
| +#endif |
| + |
| + if ((lastRC = takeOwnership((securemode)?(char*)newpwd.c_str():password)) != 0) { |
| LOG(E) << "Initial setup failed - unable to take ownership"; |
| return lastRC; |
| } |
| - if ((lastRC = activateLockingSP(password)) != 0) { |
| + if ((lastRC = activateLockingSP((securemode)?(char*)newpwd.c_str():password)) != 0) { |
| LOG(E) << "Initial setup failed - unable to activate LockingSP"; |
| return lastRC; |
| } |
| - if ((lastRC = configureLockingRange(0, DTA_DISABLELOCKING, password)) != 0) { |
| + if ((lastRC = configureLockingRange(0, DTA_DISABLELOCKING, (securemode)?(char*)newpwd.c_str():password)) != 0) { |
| LOG(E) << "Initial setup failed - unable to configure global locking range"; |
| return lastRC; |
| } |
| - if ((lastRC = setLockingRange(0, OPAL_LOCKINGSTATE::READWRITE, password)) != 0) { |
| + if ((lastRC = setLockingRange(0, OPAL_LOCKINGSTATE::READWRITE, (securemode)?(char*)newpwd.c_str():password)) != 0) { |
| LOG(E) << "Initial setup failed - unable to set global locking range RW"; |
| return lastRC; |
| } |
| - if ((lastRC = setMBRDone(1, password)) != 0){ |
| + if ((lastRC = setMBRDone(1, (securemode)?(char*)newpwd.c_str():password)) != 0){ |
| LOG(E) << "Initial setup failed - unable to Enable MBR shadow"; |
| return lastRC; |
| } |
| - if ((lastRC = setMBREnable(1, password)) != 0){ |
| + if ((lastRC = setMBREnable(1, (securemode)?(char*)newpwd.c_str():password)) != 0){ |
| LOG(E) << "Initial setup failed - unable to Enable MBR shadow"; |
| return lastRC; |
| } |
| @@ -84,7 +96,7 @@ uint8_t DtaDevOpal::initialSetup(char * password) |
| return 0; |
| } |
| |
| -uint8_t DtaDevOpal::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password) |
| +uint8_t DtaDevOpal::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode) |
| { |
| LOG(D1) << "Entering setup_SUM()"; |
| uint8_t lastRC; |
| @@ -108,7 +120,7 @@ uint8_t DtaDevOpal::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t len |
| if (!disk_info.Locking_lockingEnabled) |
| { |
| LOG(D1) << "LockingSP not enabled. Beginning initial setup flow."; |
| - if ((lastRC = takeOwnership(Admin1Password)) != 0) { |
| + if ((lastRC = takeOwnership(Admin1Password, securemode)) != 0) { |
| LOG(E) << "Setup_SUM failed - unable to take ownership"; |
| return lastRC; |
| } |
| @@ -147,7 +159,7 @@ uint8_t DtaDevOpal::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t len |
| LOG(E) << "Setup_SUM failed - unable to enable locking range"; |
| return lastRC; |
| } |
| - if ((lastRC = setNewPassword_SUM(defaultPW, (char *)userId.c_str(), password)) != 0) { |
| + if ((lastRC = setNewPassword_SUM(defaultPW, (char *)userId.c_str(), password, securemode)) != 0) { |
| LOG(E) << "Setup_SUM failed - unable to set new locking range password"; |
| return lastRC; |
| } |
| @@ -688,12 +700,13 @@ uint8_t DtaDevOpal::getAuth4User(char * userid, uint8_t uidorcpin, std::vector<u |
| LOG(D1) << "Exiting DtaDevOpal::getAuth4User()"; |
| return 0; |
| } |
| -uint8_t DtaDevOpal::setPassword(char * password, char * userid, char * newpassword) |
| +uint8_t DtaDevOpal::setPassword(char * password, char * userid, char * newpassword, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevOpal::setPassword" ; |
| uint8_t lastRC; |
| std::vector<uint8_t> userCPIN, hash; |
| session = new DtaSession(this); |
| + |
| if (NULL == session) { |
| LOG(E) << "Unable to create session object "; |
| return DTAERROR_OBJECT_CREATE_FAILED; |
| @@ -707,7 +720,28 @@ uint8_t DtaDevOpal::setPassword(char * password, char * userid, char * newpasswo |
| delete session; |
| return lastRC; |
| } |
| - DtaHashPwd(hash, newpassword, this); |
| + |
| + // Ask and confirm new password |
| +#ifdef __linux__ |
| + if (securemode) { |
| + std::string newpwd; |
| + if (askNewPassword(newpwd, true) == OPALSTATUSCODE::SUCCESS) { |
| + DtaHashPwd(hash, (char*)newpwd.c_str(), this); |
| + } |
| + else { |
| + LOG(E) << "Wrong password confirmation. Failure of password update."; |
| + delete session; |
| + lastRC = OPALSTATUSCODE::FAIL; |
| + return lastRC; |
| + } |
| + } |
| + else { |
| +#endif //__linux__ |
| + DtaHashPwd(hash, newpassword, this); |
| +#ifdef __linux__ |
| + } |
| +#endif //__linux__ |
| + |
| if ((lastRC = setTable(userCPIN, OPAL_TOKEN::PIN, hash)) != 0) { |
| LOG(E) << "Unable to set user " << userid << " new password "; |
| delete session; |
| @@ -718,7 +752,7 @@ uint8_t DtaDevOpal::setPassword(char * password, char * userid, char * newpasswo |
| LOG(D1) << "Exiting DtaDevOpal::setPassword()"; |
| return 0; |
| } |
| -uint8_t DtaDevOpal::setNewPassword_SUM(char * password, char * userid, char * newpassword) |
| +uint8_t DtaDevOpal::setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevOpal::setNewPassword_SUM"; |
| uint8_t lastRC; |
| @@ -1391,7 +1425,7 @@ uint8_t DtaDevOpal::eraseLockingRange_SUM(uint8_t lockingrange, char * password) |
| return 0; |
| } |
| |
| -uint8_t DtaDevOpal::takeOwnership(char * newpassword) |
| +uint8_t DtaDevOpal::takeOwnership(char * newpassword, bool securemode) |
| { |
| LOG(D1) << "Entering DtaDevOpal::takeOwnership()"; |
| uint8_t lastRC; |
| @@ -1399,7 +1433,7 @@ uint8_t DtaDevOpal::takeOwnership(char * newpassword) |
| LOG(E) << "Unable to read MSID password "; |
| return lastRC; |
| } |
| - if ((lastRC = setSIDPassword((char *)response.getString(4).c_str(), newpassword, 0)) != 0) { |
| + if ((lastRC = setSIDPassword((char *)response.getString(4).c_str(), newpassword, 0, 1, securemode)) != 0) { |
| LOG(E) << "takeOwnership failed"; |
| return lastRC; |
| } |
| @@ -1447,7 +1481,7 @@ uint8_t DtaDevOpal::printDefaultPassword() |
| return 0; |
| } |
| uint8_t DtaDevOpal::setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd, uint8_t hashnewpwd) |
| + uint8_t hasholdpwd, uint8_t hashnewpwd, bool securemode) |
| { |
| vector<uint8_t> hash, table; |
| LOG(D1) << "Entering DtaDevOpal::setSIDPassword()"; |
| @@ -1468,17 +1502,39 @@ uint8_t DtaDevOpal::setSIDPassword(char * oldpassword, char * newpassword, |
| for (int i = 0; i < 8; i++) { |
| table.push_back(OPALUID[OPAL_UID::OPAL_C_PIN_SID][i]); |
| } |
| + |
| hash.clear(); |
| - if (hashnewpwd) { |
| - DtaHashPwd(hash, newpassword, this); |
| - } |
| - else { |
| - hash.push_back(0xd0); |
| - hash.push_back((uint8_t)strnlen(newpassword, 255)); |
| - for (uint16_t i = 0; i < strnlen(newpassword, 255); i++) { |
| - hash.push_back(newpassword[i]); |
| - } |
| - } |
| + |
| +#ifdef __linux__ |
| + if (securemode) { |
| + // In secure mode, the password hashing is mandatory |
| + std::string newpwd; |
| + if (askNewPassword(newpwd, true) == OPALSTATUSCODE::SUCCESS) { |
| + DtaHashPwd(hash, (char*)newpwd.c_str(), this); |
| + } |
| + else { |
| + LOG(E) << "Wrong password confirmation. Failure of password update."; |
| + delete session; |
| + lastRC = DTAERROR_INVALID_PARAMETER; |
| + return lastRC; |
| + } |
| + } |
| + else { |
| +#endif //__linux__ |
| + if (hashnewpwd) { |
| + DtaHashPwd(hash, newpassword, this); |
| + } |
| + else { |
| + hash.push_back(0xd0); |
| + hash.push_back((uint8_t)strnlen(newpassword, 255)); |
| + for (uint16_t i = 0; i < strnlen(newpassword, 255); i++) { |
| + hash.push_back(newpassword[i]); |
| + } |
| + } |
| +#ifdef __linux__ |
| + } |
| +#endif //__linux__ |
| + |
| if ((lastRC = setTable(table, OPAL_TOKEN::PIN, hash)) != 0) { |
| LOG(E) << "Unable to set new SID password "; |
| delete session; |
| @@ -1833,4 +1889,22 @@ uint8_t DtaDevOpal::rawCmd(char *sp, char * hexauth, char *pass, |
| delete session; |
| LOG(D1) << "Exiting DtaDevEnterprise::rawCmd"; |
| return 0; |
| -} |
| \ No newline at end of file |
| +} |
| +#ifdef __linux__ |
| +uint8_t DtaDevOpal::askNewPassword(std::string &password, bool confirm) { |
| + uint8_t lastRC = OPALSTATUSCODE::SUCCESS; |
| + password = GetPassPhrase("Please enter the new password "); |
| + |
| + if (confirm) { |
| + std::string pwdcheck = GetPassPhrase("Please confirm the new password "); |
| + |
| + if (password != pwdcheck) { |
| + password.clear(); |
| + lastRC = OPALSTATUSCODE::FAIL; |
| + } |
| + } |
| + |
| + return lastRC; |
| +} |
| +#endif //__linux__ |
| + |
| diff --git a/Common/DtaDevOpal.h b/Common/DtaDevOpal.h |
| index 60004db..389b97f 100644 |
| --- a/Common/DtaDevOpal.h |
| +++ b/Common/DtaDevOpal.h |
| @@ -61,8 +61,9 @@ public: |
| virtual uint16_t comID() = 0; |
| /** Change the SID password from it's MSID default |
| * @param newpassword new password for SID |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t takeOwnership(char * newpassword); |
| + uint8_t takeOwnership(char * newpassword, bool securemode = false); |
| /** retrieve the MSID password */ |
| uint8_t printDefaultPassword(); |
| /** retrieve a single row from a table |
| @@ -78,9 +79,10 @@ public: |
| * @param newpassword value password is to be changed to |
| * @param hasholdpwd is the old password to be hashed before being added to the bytestream |
| * @param hashnewpwd is the new password to be hashed before being added to the bytestream |
| + * @param securemode is the new password should be interactively asked |
| */ |
| uint8_t setSIDPassword(char * oldpassword, char * newpassword, |
| - uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1); |
| + uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1, bool securemode = false); |
| /** set a single column in an object table |
| * @param table the UID of the table |
| * @param name the column name to be set |
| @@ -143,14 +145,16 @@ public: |
| * @param password current password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setPassword(char * password, char * userid, char * newpassword); |
| + uint8_t setPassword(char * password, char * userid, char * newpassword, bool securemode = false); |
| /** Set the password of a locking SP user in Single User Mode. |
| * @param password current user password |
| * @param userid the userid whose password is to be changed |
| * @param newpassword value password is to be changed to |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword); |
| + uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword, bool securemode = false); |
| /** User command to manipulate the state of a locking range. |
| * RW|RO|LK are the supported states @see OPAL_LOCKINGSTATE |
| * @param lockingrange locking range number |
| @@ -229,16 +233,18 @@ public: |
| /** User command to prepare the device for management by sedutil. |
| * Specific to the SSC that the device supports |
| * @param password the password that is to be assigned to the SSC master entities |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t initialSetup(char * password); |
| + uint8_t initialSetup(char * password, bool securemode); |
| /** User command to prepare the drive for Single User Mode and rekey a SUM locking range. |
| * @param lockingrange locking range number to enable |
| * @param start LBA to start locking range |
| * @param length length (in blocks) for locking range |
| * @param Admin1Password admin1 password for TPer |
| * @param password User password to set for locking range |
| + * @param securemode is the new password should be interactively asked |
| */ |
| - uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password); |
| + uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password, bool securemode = false); |
| /** Displays the identify and discovery 0 information */ |
| void puke(); |
| /** Dumps an object for diagnostic purposes |
| @@ -289,4 +295,12 @@ protected: |
| */ |
| lrStatus_t getLockingRange_status(uint8_t lockingrange, char * password); |
| |
| + /** Ask the user to input a new password. |
| + * This function fails if the first password and it's confirmation differs |
| + * @param password The new password entered by the user |
| + * @param confirm Is a double check necessary |
| + */ |
| +#ifdef __linux__ |
| + uint8_t askNewPassword(std::string &password, bool confirm = false); |
| +#endif //__linux__ |
| }; |
| diff --git a/Common/DtaOptions.cpp b/Common/DtaOptions.cpp |
| index fdacc40..0d1752e 100644 |
| --- a/Common/DtaOptions.cpp |
| +++ b/Common/DtaOptions.cpp |
| @@ -27,8 +27,10 @@ void usage() |
| printf("a utility to manage self encrypting drives that conform\n"); |
| printf("to the Trusted Computing Group OPAL 2.0 SSC specification\n"); |
| printf("General Usage: (see readme for extended commandset)\n"); |
| - printf("sedutil-cli <-v> <-n> <action> <options> <device>\n"); |
| + printf("sedutil-cli <-v> <-n> <-s> <action> <options> <device>\n"); |
| printf("-v (optional) increase verbosity, one to five v's\n"); |
| + printf("-s (optional) secure mode. Passwords will be asked interactively to the user.\n"); |
| + printf(" Available only on linux.\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("actions \n"); |
| @@ -130,11 +132,31 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| LOG(D) << "Log level set to " << CLog::ToString(CLog::FromInt(loggingLevel)); |
| LOG(D) << "sedutil version : " << GIT_VERSION; |
| } |
| + else if (!(strcmp("-s", argv[i]))) { |
| + baseOptions += 1; |
| +#ifdef __linux__ |
| + opts->secure_mode = true; |
| + opts->no_hash_passwords = false; |
| +#else |
| + LOG(E) << "Secure mode not implemented"; |
| +#endif //__linux__ |
| + } |
| else if (!(strcmp("-n", argv[i]))) { |
| - baseOptions += 1; |
| - opts->no_hash_passwords = true; |
| - LOG(D) << "Password hashing is disabled"; |
| - } |
| + baseOptions += 1; |
| +#ifdef __linux__ |
| + if (!opts->secure_mode) { |
| +#endif //__linux__ |
| + opts->no_hash_passwords = true; |
| + LOG(D) << "Password hashing is disabled"; |
| +#ifdef __linux__ |
| + } |
| + else { |
| + LOG(D) << "No password hashing incompatible with secure mode"; |
| + } |
| + LOG(D) << "Disabling password hashing in secure mode (-s)"; |
| + opts->no_hash_passwords = true; |
| +#endif //__linux__ |
| + } |
| else if (!strcmp("-l", argv[i])) { |
| baseOptions += 1; |
| opts->output_format = sedutilNormal; |
| @@ -146,10 +168,10 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| LOG(E) << "Argument " << (uint16_t) i << " (" << argv[i] << ") should be a command"; |
| return DTAERROR_INVALID_COMMAND; |
| } |
| - BEGIN_OPTION(initialSetup, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(setSIDPassword, 3) OPTION_IS(password) OPTION_IS(newpassword) |
| + BEGIN_OPTION(initialSetup, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(setSIDPassword, 3, 1) OPTION_IS(password) OPTION_IS(newpassword) |
| OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(setup_SUM, 6) |
| + BEGIN_OPTION(setup_SUM, 6, 4) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -173,20 +195,20 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(newpassword) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setAdmin1Pwd, 3) OPTION_IS(password) OPTION_IS(newpassword) |
| + BEGIN_OPTION(setAdmin1Pwd, 3, 1) OPTION_IS(password) OPTION_IS(newpassword) |
| OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(loadPBAimage, 3) OPTION_IS(password) OPTION_IS(pbafile) |
| + BEGIN_OPTION(loadPBAimage, 3, 2) OPTION_IS(password) OPTION_IS(pbafile) |
| OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(revertTPer, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(revertNoErase, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(PSIDrevert, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(PSIDrevertAdminSP, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(yesIreallywanttoERASEALLmydatausingthePSID, 2) OPTION_IS(password) |
| + BEGIN_OPTION(revertTPer, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(revertNoErase, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(PSIDrevert, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(PSIDrevertAdminSP, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(yesIreallywanttoERASEALLmydatausingthePSID, 2, 1) OPTION_IS(password) |
| OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(enableuser, 2) OPTION_IS(password) OPTION_IS(userid) |
| + BEGIN_OPTION(enableuser, 3, 2) OPTION_IS(password) OPTION_IS(userid) |
| OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(activateLockingSP, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(activateLockingSP_SUM, 3) |
| + BEGIN_OPTION(activateLockingSP, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(activateLockingSP_SUM, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -205,7 +227,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| TESTARG(15, lockingrange, 15) |
| TESTFAIL("Invalid Locking Range (0-15)") |
| OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(eraseLockingRange_SUM, 3) |
| + BEGIN_OPTION(eraseLockingRange_SUM, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -224,10 +246,10 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| TESTARG(15, lockingrange, 15) |
| TESTFAIL("Invalid Locking Range (1-15)") |
| OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(query, 1) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(scan, 0) END_OPTION |
| - BEGIN_OPTION(isValidSED, 1) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(eraseLockingRange, 3) |
| + BEGIN_OPTION(query, 1, 1) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(scan, 0, 0) END_OPTION |
| + BEGIN_OPTION(isValidSED, 1, 1) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(eraseLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -248,14 +270,14 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(takeOwnership, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(revertLockingSP, 2) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(setPassword, 4) OPTION_IS(password) OPTION_IS(userid) |
| + BEGIN_OPTION(takeOwnership, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(revertLockingSP, 2, 1) OPTION_IS(password) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(setPassword, 4, 2) OPTION_IS(password) OPTION_IS(userid) |
| OPTION_IS(newpassword) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(setPassword_SUM, 4) OPTION_IS(password) OPTION_IS(userid) |
| + BEGIN_OPTION(setPassword_SUM, 4, 2) OPTION_IS(password) OPTION_IS(userid) |
| OPTION_IS(newpassword) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(validatePBKDF2, 0) END_OPTION |
| - BEGIN_OPTION(setMBREnable, 3) |
| + BEGIN_OPTION(validatePBKDF2, 0, 0) END_OPTION |
| + BEGIN_OPTION(setMBREnable, 3, 2) |
| TESTARG(ON, mbrstate, 1) |
| TESTARG(on, mbrstate, 1) |
| TESTARG(off, mbrstate, 0) |
| @@ -264,7 +286,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setMBRDone, 3) |
| + BEGIN_OPTION(setMBRDone, 3, 2) |
| TESTARG(ON, mbrstate, 1) |
| TESTARG(on, mbrstate, 1) |
| TESTARG(off, mbrstate, 0) |
| @@ -273,7 +295,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setLockingRange, 4) |
| + BEGIN_OPTION(setLockingRange, 4, 3) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -301,7 +323,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setLockingRange_SUM, 4) |
| + BEGIN_OPTION(setLockingRange_SUM, 4, 3) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -329,7 +351,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(enableLockingRange, 3) |
| + BEGIN_OPTION(enableLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -350,7 +372,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(disableLockingRange, 3) |
| + BEGIN_OPTION(disableLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -371,7 +393,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setupLockingRange, 5) |
| + BEGIN_OPTION(setupLockingRange, 5, 4) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -394,7 +416,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setupLockingRange_SUM, 5) |
| + BEGIN_OPTION(setupLockingRange_SUM, 5, 4) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -417,7 +439,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(readonlyLockingRange, 3) |
| + BEGIN_OPTION(readonlyLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -438,11 +460,11 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(listLockingRanges, 2) |
| + BEGIN_OPTION(listLockingRanges, 2, 1) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(listLockingRange, 3) |
| + BEGIN_OPTION(listLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -463,7 +485,7 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(rekeyLockingRange, 3) |
| + BEGIN_OPTION(rekeyLockingRange, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -484,11 +506,11 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setBandsEnabled, 2) |
| + BEGIN_OPTION(setBandsEnabled, 2, 1) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(setBandEnabled, 3) |
| + BEGIN_OPTION(setBandEnabled, 3, 2) |
| TESTARG(0, lockingrange, 0) |
| TESTARG(1, lockingrange, 1) |
| TESTARG(2, lockingrange, 2) |
| @@ -509,9 +531,9 @@ uint8_t DtaOptions(int argc, char * argv[], DTA_OPTIONS * opts) |
| OPTION_IS(password) |
| OPTION_IS(device) |
| END_OPTION |
| - BEGIN_OPTION(objDump, 5) i += 4; OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(printDefaultPassword, 1) OPTION_IS(device) END_OPTION |
| - BEGIN_OPTION(rawCmd, 7) i += 6; OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(objDump, 5, 5) i += 4; OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(printDefaultPassword, 1, 1) OPTION_IS(device) END_OPTION |
| + BEGIN_OPTION(rawCmd, 7, 7) i += 6; OPTION_IS(device) END_OPTION |
| else { |
| LOG(E) << "Invalid command line argument " << argv[i]; |
| return DTAERROR_INVALID_COMMAND; |
| diff --git a/Common/DtaOptions.h b/Common/DtaOptions.h |
| index c012af1..4ae3bc2 100644 |
| --- a/Common/DtaOptions.h |
| +++ b/Common/DtaOptions.h |
| @@ -43,6 +43,8 @@ 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 secure_mode; /** global parameter, enable the secure mode */ |
| + bool ask_password; /** global parameter, to know if the password needs to be interactively asked to the user */ |
| sedutiloutput output_format; |
| } DTA_OPTIONS; |
| /** Print a usage message */ |
| @@ -98,16 +100,18 @@ typedef enum _sedutiloption { |
| rawCmd, |
| |
| } sedutiloption; |
| + |
| /** verify the number of arguments passed */ |
| -#define CHECKARGS(x) \ |
| -if((x+baseOptions) != argc) { \ |
| - LOG(E) << "Incorrect number of paramaters for " << argv[i] << " command"; \ |
| - return 100; \ |
| - } |
| +#define CHECKARGS(x1, x2) \ |
| + int a = opts->secure_mode? x2: x1;\ |
| + if((a+baseOptions) != argc) { \ |
| + LOG(E) << "Incorrect number of paramaters for " << argv[i] << " command"; \ |
| + return 100; \ |
| + } |
| /** Test the command input for a recognized argument */ |
| -#define BEGIN_OPTION(cmdstring,args) \ |
| +#define BEGIN_OPTION(cmdstring,args,args_secure) \ |
| else if (!(strcasecmp(#cmdstring, &argv[i][2]))) { \ |
| - CHECKARGS(args) \ |
| + CHECKARGS(args, args_secure) \ |
| opts->action = sedutiloption::cmdstring; \ |
| |
| /** end of an OPTION */ |
| @@ -126,6 +130,22 @@ i++; |
| |
| /** set the argc value for this parameter in the options structure */ |
| #define OPTION_IS(option_field) \ |
| - opts->option_field = ++i; |
| + if (opts->secure_mode && \ |
| + (!(strcasecmp(#option_field, "password")) || \ |
| + !(strcasecmp(#option_field, "newpassword")))) { \ |
| + opts->option_field = 255; \ |
| + if (opts->action != sedutiloption::initialSetup)\ |
| + opts->ask_password = true; \ |
| + } \ |
| + else { \ |
| + opts->option_field = ++i; \ |
| + }\ |
| + |
| +/** Return the interactive password in secure mode or command line arg*/ |
| +#define GET_PASSWORD() \ |
| + opts.secure_mode? (char*) interactive_password.c_str() : argv[opts.password]\ |
| + |
| +#define GET_NEW_PASSWORD() \ |
| + opts.secure_mode? (char*)"" : argv[opts.newpassword]\ |
| |
| #endif /* _DTAOPTIONS_H */ |
| diff --git a/Common/sedutil.cpp b/Common/sedutil.cpp |
| index fe6df19..7053cd3 100644 |
| --- a/Common/sedutil.cpp |
| +++ b/Common/sedutil.cpp |
| @@ -54,10 +54,17 @@ int main(int argc, char * argv[]) |
| { |
| DTA_OPTIONS opts; |
| DtaDev *tempDev = NULL, *d = NULL; |
| + std::string interactive_password; |
| if (DtaOptions(argc, argv, &opts)) { |
| return DTAERROR_COMMAND_ERROR; |
| } |
| |
| +#ifdef __linux__ |
| + if (opts.secure_mode && opts.ask_password) { |
| + interactive_password = GetPassPhrase("Please enter password "); |
| + } |
| +#endif //__linux__ |
| + |
| if ((opts.action != sedutiloption::scan) && |
| (opts.action != sedutiloption::validatePBKDF2) && |
| (opts.action != sedutiloption::isValidSED)) { |
| @@ -99,101 +106,101 @@ int main(int argc, char * argv[]) |
| switch (opts.action) { |
| case sedutiloption::initialSetup: |
| LOG(D) << "Performing initial setup to use sedutil on drive " << argv[opts.device]; |
| - return (d->initialSetup(argv[opts.password])); |
| + return (d->initialSetup(GET_PASSWORD(), opts.secure_mode)); |
| case sedutiloption::setup_SUM: |
| LOG(D) << "Performing SUM setup on drive " << argv[opts.device]; |
| return (d->setup_SUM(opts.lockingrange, atoll(argv[opts.lrstart]), |
| - atoll(argv[opts.lrlength]), argv[opts.password], argv[opts.newpassword])); |
| + atoll(argv[opts.lrlength]), GET_PASSWORD(), GET_NEW_PASSWORD(), opts.secure_mode)); |
| break; |
| case sedutiloption::setSIDPassword: |
| LOG(D) << "Performing setSIDPassword "; |
| - return d->setSIDPassword(argv[opts.password], argv[opts.newpassword]); |
| + return d->setSIDPassword(GET_PASSWORD(), GET_NEW_PASSWORD(), opts.no_hash_passwords? 0 : 1, opts.no_hash_passwords? 0 : 1, opts.secure_mode); |
| break; |
| case sedutiloption::setAdmin1Pwd: |
| LOG(D) << "Performing setPAdmin1Pwd "; |
| - return d->setPassword(argv[opts.password], (char *) "Admin1", |
| - argv[opts.newpassword]); |
| + return d->setPassword(GET_PASSWORD(), (char *) "Admin1", |
| + GET_NEW_PASSWORD(), opts.secure_mode); |
| break; |
| case sedutiloption::loadPBAimage: |
| LOG(D) << "Loading PBA image " << argv[opts.pbafile] << " to " << opts.device; |
| - return d->loadPBA(argv[opts.password], argv[opts.pbafile]); |
| + return d->loadPBA(GET_PASSWORD(), argv[opts.pbafile]); |
| break; |
| case sedutiloption::setLockingRange: |
| LOG(D) << "Setting Locking Range " << (uint16_t) opts.lockingrange << " " << (uint16_t) opts.lockingstate; |
| - return d->setLockingRange(opts.lockingrange, opts.lockingstate, argv[opts.password]); |
| + return d->setLockingRange(opts.lockingrange, opts.lockingstate, GET_PASSWORD()); |
| break; |
| case sedutiloption::setLockingRange_SUM: |
| LOG(D) << "Setting Locking Range " << (uint16_t)opts.lockingrange << " " << (uint16_t)opts.lockingstate << " in Single User Mode"; |
| - return d->setLockingRange_SUM(opts.lockingrange, opts.lockingstate, argv[opts.password]); |
| + return d->setLockingRange_SUM(opts.lockingrange, opts.lockingstate, GET_PASSWORD()); |
| break; |
| case sedutiloption::enableLockingRange: |
| LOG(D) << "Enabling Locking Range " << (uint16_t) opts.lockingrange; |
| return (d->configureLockingRange(opts.lockingrange, |
| - (DTA_READLOCKINGENABLED | DTA_WRITELOCKINGENABLED), argv[opts.password])); |
| + (DTA_READLOCKINGENABLED | DTA_WRITELOCKINGENABLED), GET_PASSWORD())); |
| break; |
| case sedutiloption::disableLockingRange: |
| LOG(D) << "Disabling Locking Range " << (uint16_t) opts.lockingrange; |
| return (d->configureLockingRange(opts.lockingrange, DTA_DISABLELOCKING, |
| - argv[opts.password])); |
| + GET_PASSWORD())); |
| break; |
| case sedutiloption::readonlyLockingRange: |
| LOG(D) << "Enabling Locking Range " << (uint16_t)opts.lockingrange; |
| return (d->configureLockingRange(opts.lockingrange, |
| - DTA_WRITELOCKINGENABLED, argv[opts.password])); |
| + DTA_WRITELOCKINGENABLED, GET_PASSWORD())); |
| break; |
| case sedutiloption::setupLockingRange: |
| LOG(D) << "Setup Locking Range " << (uint16_t)opts.lockingrange; |
| return (d->setupLockingRange(opts.lockingrange, atoll(argv[opts.lrstart]), |
| - atoll(argv[opts.lrlength]), argv[opts.password])); |
| + atoll(argv[opts.lrlength]), GET_PASSWORD())); |
| break; |
| case sedutiloption::setupLockingRange_SUM: |
| LOG(D) << "Setup Locking Range " << (uint16_t)opts.lockingrange << " in Single User Mode"; |
| return (d->setupLockingRange_SUM(opts.lockingrange, atoll(argv[opts.lrstart]), |
| - atoll(argv[opts.lrlength]), argv[opts.password])); |
| + atoll(argv[opts.lrlength]), GET_PASSWORD())); |
| break; |
| case sedutiloption::listLockingRanges: |
| LOG(D) << "List Locking Ranges "; |
| - return (d->listLockingRanges(argv[opts.password], -1)); |
| + return (d->listLockingRanges(GET_PASSWORD(), -1)); |
| break; |
| case sedutiloption::listLockingRange: |
| LOG(D) << "List Locking Range[" << opts.lockingrange << "]"; |
| - return (d->listLockingRanges(argv[opts.password], opts.lockingrange)); |
| + return (d->listLockingRanges(GET_PASSWORD(), opts.lockingrange)); |
| break; |
| case sedutiloption::rekeyLockingRange: |
| LOG(D) << "Rekey Locking Range[" << opts.lockingrange << "]"; |
| - return (d->rekeyLockingRange(opts.lockingrange, argv[opts.password])); |
| + return (d->rekeyLockingRange(opts.lockingrange, GET_PASSWORD())); |
| break; |
| case sedutiloption::setBandsEnabled: |
| LOG(D) << "Set bands Enabled"; |
| - return (d->setBandsEnabled(-1, argv[opts.password])); |
| + return (d->setBandsEnabled(-1, GET_PASSWORD())); |
| break; |
| case sedutiloption::setBandEnabled: |
| LOG(D) << "Set band[" << opts.lockingrange << "] enabled"; |
| - return (d->setBandsEnabled(opts.lockingrange, argv[opts.password])); |
| + return (d->setBandsEnabled(opts.lockingrange, GET_PASSWORD())); |
| break; |
| case sedutiloption::setMBRDone: |
| LOG(D) << "Setting MBRDone " << (uint16_t)opts.mbrstate; |
| - return (d->setMBRDone(opts.mbrstate, argv[opts.password])); |
| + return (d->setMBRDone(opts.mbrstate, GET_PASSWORD())); |
| break; |
| case sedutiloption::setMBREnable: |
| LOG(D) << "Setting MBREnable " << (uint16_t)opts.mbrstate; |
| - return (d->setMBREnable(opts.mbrstate, argv[opts.password])); |
| + return (d->setMBREnable(opts.mbrstate, GET_PASSWORD())); |
| break; |
| case sedutiloption::enableuser: |
| LOG(D) << "Performing enable user for user " << argv[opts.userid]; |
| - return d->enableUser(argv[opts.password], argv[opts.userid]); |
| + return d->enableUser(GET_PASSWORD(), argv[opts.userid]); |
| break; |
| case sedutiloption::activateLockingSP: |
| LOG(D) << "Activating the LockingSP on" << argv[opts.device]; |
| - return d->activateLockingSP(argv[opts.password]); |
| + return d->activateLockingSP(GET_PASSWORD()); |
| break; |
| case sedutiloption::activateLockingSP_SUM: |
| LOG(D) << "Activating the LockingSP on" << argv[opts.device]; |
| - return d->activateLockingSP_SUM(opts.lockingrange, argv[opts.password]); |
| + return d->activateLockingSP_SUM(opts.lockingrange, GET_PASSWORD()); |
| break; |
| case sedutiloption::eraseLockingRange_SUM: |
| LOG(D) << "Erasing LockingRange " << opts.lockingrange << " on" << argv[opts.device]; |
| - return d->eraseLockingRange_SUM(opts.lockingrange, argv[opts.password]); |
| + return d->eraseLockingRange_SUM(opts.lockingrange, GET_PASSWORD()); |
| break; |
| case sedutiloption::query: |
| LOG(D) << "Performing diskquery() on " << argv[opts.device]; |
| @@ -210,29 +217,29 @@ int main(int argc, char * argv[]) |
| break; |
| case sedutiloption::takeOwnership: |
| LOG(D) << "Taking Ownership of the drive at" << argv[opts.device]; |
| - return d->takeOwnership(argv[opts.password]); |
| + return d->takeOwnership(GET_PASSWORD(), opts.secure_mode); |
| break; |
| case sedutiloption::revertLockingSP: |
| LOG(D) << "Performing revertLockingSP on " << argv[opts.device]; |
| - return d->revertLockingSP(argv[opts.password], 0); |
| + return d->revertLockingSP(GET_PASSWORD(), 0); |
| break; |
| case sedutiloption::setPassword: |
| LOG(D) << "Performing setPassword for user " << argv[opts.userid]; |
| - return d->setPassword(argv[opts.password], argv[opts.userid], |
| - argv[opts.newpassword]); |
| + return d->setPassword(GET_PASSWORD(), argv[opts.userid], |
| + GET_NEW_PASSWORD(), opts.secure_mode); |
| break; |
| case sedutiloption::setPassword_SUM: |
| LOG(D) << "Performing setPassword in SUM mode for user " << argv[opts.userid]; |
| - return d->setNewPassword_SUM(argv[opts.password], argv[opts.userid], |
| - argv[opts.newpassword]); |
| + return d->setNewPassword_SUM(GET_PASSWORD(), argv[opts.userid], |
| + GET_NEW_PASSWORD(), opts.secure_mode); |
| break; |
| case sedutiloption::revertTPer: |
| LOG(D) << "Performing revertTPer on " << argv[opts.device]; |
| - return d->revertTPer(argv[opts.password], 0, 0); |
| + return d->revertTPer(GET_PASSWORD(), 0, 0); |
| break; |
| case sedutiloption::revertNoErase: |
| LOG(D) << "Performing revertLockingSP keep global locking range on " << argv[opts.device]; |
| - return d->revertLockingSP(argv[opts.password], 1); |
| + return d->revertLockingSP(GET_PASSWORD(), 1); |
| break; |
| case sedutiloption::validatePBKDF2: |
| LOG(D) << "Performing PBKDF2 validation "; |
| @@ -240,16 +247,16 @@ int main(int argc, char * argv[]) |
| break; |
| case sedutiloption::yesIreallywanttoERASEALLmydatausingthePSID: |
| case sedutiloption::PSIDrevert: |
| - LOG(D) << "Performing a PSID Revert on " << argv[opts.device] << " with password " << argv[opts.password]; |
| - return d->revertTPer(argv[opts.password], 1, 0); |
| + LOG(D) << "Performing a PSID Revert on " << argv[opts.device] << " with password " << GET_PASSWORD(); |
| + return d->revertTPer(GET_PASSWORD(), 1, 0); |
| break; |
| case sedutiloption::PSIDrevertAdminSP: |
| - LOG(D) << "Performing a PSID RevertAdminSP on " << argv[opts.device] << " with password " << argv[opts.password]; |
| - return d->revertTPer(argv[opts.password], 1, 1); |
| + LOG(D) << "Performing a PSID RevertAdminSP on " << argv[opts.device] << " with password " << GET_PASSWORD(); |
| + return d->revertTPer(GET_PASSWORD(), 1, 1); |
| break; |
| case sedutiloption::eraseLockingRange: |
| LOG(D) << "Erase Locking Range " << (uint16_t)opts.lockingrange; |
| - return (d->eraseLockingRange(opts.lockingrange, argv[opts.password])); |
| + return (d->eraseLockingRange(opts.lockingrange, GET_PASSWORD())); |
| break; |
| case sedutiloption::objDump: |
| LOG(D) << "Performing objDump " ; |
| diff --git a/linux/os.h b/linux/os.h |
| index 89a798e..e65a0c4 100644 |
| --- a/linux/os.h |
| +++ b/linux/os.h |
| @@ -33,3 +33,5 @@ along with sedutil. If not, see <http://www.gnu.org/licenses/>. |
| #define SNPRINTF snprintf |
| #define DEVICEMASK snprintf(devname,23,"/dev/sd%c",(char) 0x61+i) |
| #define DEVICEEXAMPLE "/dev/sdc" |
| + |
| +#include "../LinuxPBA/GetPassPhrase.h" |
| -- |
| 2.40.0.577.gac1e443424-goog |
| |