diff --git a/.gitignore b/.gitignore
index 1d30e98f..734424d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,7 @@ build/
*.tmp
*.tmp_proj
*.log
+*.vs
*.vspscc
*.vssscc
.builds
@@ -195,4 +196,9 @@ Doxygen/
# inno installer output
windows/installer/Output/
# hacked exe files for different flavors
-windows/installer/exe
\ No newline at end of file
+windows/installer/exe
+# Xcode
+## User settings
+xcuserdata/
+
+Version.h
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..41134672
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,12 @@
+[submodule "macos/oui"]
+ path = macos/CLI/oui
+ url = git@github.com:Drive-Trust-Alliance/oui.git
+ branch = develop
+[submodule "macos/CLI.OpenSource/oui"]
+ path = Customizations/macos/CLI.OpenSource/oui
+ url = git@github.com:Drive-Trust-Alliance/oui.git
+ branch = develop
+[submodule "oui"]
+ path = oui
+ url = git@github.com:Drive-Trust-Alliance/oui.git
+ branch = develop
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..0e40fe8f
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+
+# Default ignored files
+/workspace.xml
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 00000000..105ce2da
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..7ba73c25
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..3a654885
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/py.iml b/.idea/py.iml
new file mode 100644
index 00000000..67116063
--- /dev/null
+++ b/.idea/py.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Common/ATAStructures.h b/Common/ATAStructures.h
new file mode 100644
index 00000000..3949c01a
--- /dev/null
+++ b/Common/ATAStructures.h
@@ -0,0 +1,50 @@
+/* C:B**************************************************************************
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+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********************************************************************** */
+#pragma once
+#if !defined(__ATASTRUCTURES_H_INCLUDED__)
+#define __ATASTRUCTURES_H_INCLUDED__
+
+/** ATA commands needed for TCG storage communication */
+typedef enum _ATACOMMAND {
+ IF_RECV = 0x5c,
+ IF_SEND = 0x5e,
+ IDENTIFY = 0xec,
+} ATACOMMAND;
+
+typedef enum _ATAPROTOCOL {
+ // Per e.g. https://www.t10.org/ftp/t10/document.04/04-262r8.pdf
+ HARD_RESET = 0,
+ SRST = 1,
+ // 2 Reserved
+ NON_DATA = 3,
+ PIO_DATA_IN = 4,
+ PIO_DATA_OUT = 5,
+ DMA = 6,
+ DMA_QUEUED = 7,
+ DEVICE_DIAGNOSTIC = 8,
+ DEVICE_RESET = 9,
+ UDMA_DATA_IN = 10,
+ UDMA_DATA_OUT = 11,
+ FPDMA = 12,
+ // 13, 14 Reserved
+ RETURN_RESPONSE_INFORMATION = 15
+} ATAPROTOCOL;
+
+#endif //!defined(__ATASTRUCTURES_H_INCLUDED__)
diff --git a/Common/Copyright.txt b/Common/Copyright.txt
index 22c382a4..263a1ef2 100644
--- a/Common/Copyright.txt
+++ b/Common/Copyright.txt
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
diff --git a/Common/Customizations b/Common/Customizations
new file mode 120000
index 00000000..c07777fb
--- /dev/null
+++ b/Common/Customizations
@@ -0,0 +1 @@
+../Customizations/Common
\ No newline at end of file
diff --git a/Common/DtaAnnotatedDump.cpp b/Common/DtaAnnotatedDump.cpp
index c5eab787..4a412ae9 100644
--- a/Common/DtaAnnotatedDump.cpp
+++ b/Common/DtaAnnotatedDump.cpp
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
@@ -21,6 +21,8 @@ along with sedutil. If not, see .
#include "os.h"
#include
+#include
+
#include
#include
#include
@@ -356,7 +358,7 @@ uint8_t DtaAnnotatedDump(ATACOMMAND cmd, void * buffer, uint32_t bufferlen)
fprintf(stream, "<< 0x%2.2X\n >>\n", cmd);
// echo header
- OPALHeader h;
+ DTA_Header h;
memcpy(&h, buffer, sizeof(h));
IFLOG(D1)
{
diff --git a/Common/DtaAnnotatedDump.h b/Common/DtaAnnotatedDump.h
index 734c8ebc..47205572 100644
--- a/Common/DtaAnnotatedDump.h
+++ b/Common/DtaAnnotatedDump.h
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
diff --git a/Common/DtaAuthorizeSedutilExecution.h b/Common/DtaAuthorizeSedutilExecution.h
new file mode 100644
index 00000000..d5ebb703
--- /dev/null
+++ b/Common/DtaAuthorizeSedutilExecution.h
@@ -0,0 +1,26 @@
+/* C:B**************************************************************************
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+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********************************************************************** */
+
+// Authorize this sedutil-cli run.
+// Check licenses, etc., if appropriate.
+//
+// Returns true if OK to run, false if process should exit.
+//
+extern "C" bool authorize_sedutil_execution(int argc, char * argv[]);
diff --git a/Common/DtaCommand.cpp b/Common/DtaCommand.cpp
index 0148d34d..9c5978e1 100644
--- a/Common/DtaCommand.cpp
+++ b/Common/DtaCommand.cpp
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
@@ -19,6 +19,7 @@ along with sedutil. If not, see .
* C:E********************************************************************** */
#include "os.h"
#include
+#include
#include "DtaCommand.h"
#include "DtaEndianFixup.h"
#include "DtaHexDump.h"
@@ -29,20 +30,25 @@ using namespace std;
DtaCommand::DtaCommand()
{
LOG(D1) << "Creating DtaCommand()";
- cmdbuf = commandbuffer + IO_BUFFER_ALIGNMENT;
+ cmdbuf = commandbuffer + IO_BUFFER_ALIGNMENT - 1;
cmdbuf = (uint8_t*)((uintptr_t)cmdbuf & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
- respbuf = responsebuffer + IO_BUFFER_ALIGNMENT;
+ assert(cmdbuf + MAX_BUFFER_LENGTH <= commandbuffer + sizeof(commandbuffer));
+ respbuf = responsebuffer + IO_BUFFER_ALIGNMENT - 1;
respbuf = (uint8_t*)((uintptr_t)respbuf & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
+ assert(respbuf + MIN_BUFFER_LENGTH <= responsebuffer + sizeof(responsebuffer));
}
/* Fill in the header information and format the call */
DtaCommand::DtaCommand(OPAL_UID InvokingUid, OPAL_METHOD method)
{
LOG(D1) << "Creating DtaCommand(ID, InvokingUid, method)";
- cmdbuf = commandbuffer + IO_BUFFER_ALIGNMENT;
+ LOG(D2) << "InvokingUID is " << InvokingUid << ", method is " << method;
+ cmdbuf = commandbuffer + IO_BUFFER_ALIGNMENT - 1;
cmdbuf = (uint8_t*)((uintptr_t)cmdbuf & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
- respbuf = responsebuffer + IO_BUFFER_ALIGNMENT;
+ assert(cmdbuf + MAX_BUFFER_LENGTH <= commandbuffer + sizeof(commandbuffer));
+ respbuf = responsebuffer + IO_BUFFER_ALIGNMENT - 1;
respbuf = (uint8_t*)((uintptr_t)respbuf & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
+ assert(respbuf + MIN_BUFFER_LENGTH <= responsebuffer + sizeof(responsebuffer));
reset(InvokingUid, method);
}
@@ -52,19 +58,21 @@ DtaCommand::reset()
LOG(D1) << "Entering DtaCommand::reset()";
memset(cmdbuf, 0, MAX_BUFFER_LENGTH);
memset(respbuf, 0, MIN_BUFFER_LENGTH);
- bufferpos = sizeof (OPALHeader);
+ bufferpos = sizeof (DTA_Header);
}
-void
+void
DtaCommand::reset(OPAL_UID InvokingUid, vector method){
- LOG(D1) << "Entering DtaCommand::reset(OPAL_UID,uint8_t)";
+ LOG(D1) << "Entering DtaCommand::reset(OPAL_UID,vector)";
+ LOG(D2) << "InvokingUID is " << InvokingUid << ", method is " << method.data();
reset();
cmdbuf[bufferpos++] = OPAL_TOKEN::CALL;
addToken(InvokingUid);
addToken(method);
}
-void
+void
DtaCommand::reset(vector InvokingUid, vector method){
- LOG(D1) << "Entering DtaCommand::reset(uint8_t,uint8_t)";
+ LOG(D1) << "Entering DtaCommand::reset(vector,vector)";
+ LOG(D2) << "InvokingUID is " << InvokingUid.data() << ", method is " << method.data();
reset();
cmdbuf[bufferpos++] = OPAL_TOKEN::CALL;
addToken(InvokingUid);
@@ -75,7 +83,8 @@ void
DtaCommand::reset(OPAL_UID InvokingUid, OPAL_METHOD method)
{
LOG(D1) << "Entering DtaCommand::reset(OPAL_UID, OPAL_METHOD)";
- reset();
+ LOG(D2) << "InvokingUID is " << InvokingUid << ", method is " << method;
+ reset();
cmdbuf[bufferpos++] = OPAL_TOKEN::CALL;
addToken(InvokingUid);
cmdbuf[bufferpos++] = OPAL_SHORT_ATOM::BYTESTRING8;
@@ -88,6 +97,7 @@ DtaCommand::addToken(uint64_t number)
{
int startat = 0;
LOG(D1) << "Entering DtaCommand::addToken(uint64_t)";
+ LOG(D2) << "number is " << number;
if (number < 64) {
cmdbuf[bufferpos++] = (uint8_t) number & 0x000000000000003f;
}
@@ -118,6 +128,7 @@ void
DtaCommand::addToken(vector token)
{
LOG(D1) << "Entering addToken(vector)";
+ LOG(D2) << "token is " << token.data();
for (uint32_t i = 0; i < token.size(); i++) {
cmdbuf[bufferpos++] = token[i];
}
@@ -126,7 +137,8 @@ DtaCommand::addToken(vector token)
void
DtaCommand::addToken(const char * bytestring)
{
- LOG(D1) << "Entering DtaCommand::addToken(const char * )";
+ LOG(D1) << "Entering DtaCommand::addToken(const char *)";
+ LOG(D2) << "bytestring is \"" << bytestring << "\"";
uint16_t length = (uint16_t) strlen(bytestring);
if (length == 0) {
/* null token e.g. default password */
@@ -156,6 +168,7 @@ void
DtaCommand::addToken(OPAL_TOKEN token)
{
LOG(D1) << "Entering DtaCommand::addToken(OPAL_TOKEN)";
+ LOG(D2) << "token is " << token;
cmdbuf[bufferpos++] = (uint8_t) token;
}
@@ -163,6 +176,7 @@ void
DtaCommand::addToken(OPAL_SHORT_ATOM token)
{
LOG(D1) << "Entering DtaCommand::addToken(OPAL_SHORT_ATOM)";
+ LOG(D2) << "token is " << token;
cmdbuf[bufferpos++] = (uint8_t)token;
}
@@ -170,6 +184,7 @@ void
DtaCommand::addToken(OPAL_TINY_ATOM token)
{
LOG(D1) << "Entering DtaCommand::addToken(OPAL_TINY_ATOM)";
+ LOG(D2) << "token is " << token;
cmdbuf[bufferpos++] = (uint8_t) token;
}
@@ -177,15 +192,27 @@ void
DtaCommand::addToken(OPAL_UID token)
{
LOG(D1) << "Entering DtaCommand::addToken(OPAL_UID)";
+ LOG(D2) << "token is " << token;
cmdbuf[bufferpos++] = OPAL_SHORT_ATOM::BYTESTRING8;
memcpy(&cmdbuf[bufferpos], &OPALUID[token][0], 8);
bufferpos += 8;
}
+void
+DtaCommand::addToken(OPAL_UID token,uint8_t factor)
+{
+ LOG(D1) << "Entering DtaCommand::addToken(OPAL_UID, factor)";
+ LOG(D2) << "token is " << token << ", factor is " << factor;
+ cmdbuf[bufferpos++] = OPAL_SHORT_ATOM::BYTESTRING4;
+ memcpy(&cmdbuf[bufferpos], &OPALUID[token][0], factor);
+ bufferpos += factor;
+}
+
void
DtaCommand::complete(uint8_t EOD)
{
LOG(D1) << "Entering DtaCommand::complete(uint8_t EOD)";
+ LOG(D2) << "EOD is " << (bool)EOD;
if (EOD) {
cmdbuf[bufferpos++] = OPAL_TOKEN::ENDOFDATA;
cmdbuf[bufferpos++] = OPAL_TOKEN::STARTLIST;
@@ -195,15 +222,15 @@ DtaCommand::complete(uint8_t EOD)
cmdbuf[bufferpos++] = OPAL_TOKEN::ENDLIST;
}
/* fill in the lengths and add the modulo 4 padding */
- OPALHeader * hdr;
- hdr = (OPALHeader *) cmdbuf;
- hdr->subpkt.length = SWAP32(bufferpos - (sizeof (OPALHeader)));
+ DTA_Header * hdr;
+ hdr = (DTA_Header *) cmdbuf;
+ hdr->subpkt.length = SWAP32(bufferpos - (uint32_t)(sizeof (DTA_Header)));
while (bufferpos % 4 != 0) {
cmdbuf[bufferpos++] = 0x00;
}
- hdr->pkt.length = SWAP32((bufferpos - sizeof (OPALComPacket))
- - sizeof (OPALPacket));
- hdr->cp.length = SWAP32(bufferpos - sizeof (OPALComPacket));
+ hdr->pkt.length = SWAP32(bufferpos - (uint32_t)(sizeof (DTA_ComPacketHeader))
+ - (uint32_t)(sizeof (DTA_PacketHeader)));
+ hdr->cp.length = SWAP32(bufferpos - (uint32_t)(sizeof (DTA_ComPacketHeader)));
if (bufferpos > MAX_BUFFER_LENGTH) {
LOG(D1) << " Standard Buffer Overrun " << bufferpos;
exit(EXIT_FAILURE);
@@ -214,7 +241,8 @@ void
DtaCommand::changeInvokingUid(std::vector Invoker)
{
LOG(D1) << "Entering DtaCommand::changeInvokingUid()";
- int offset = sizeof (OPALHeader) + 1; /* bytes 2-9 */
+ LOG(D2) << "Invoker is " << Invoker.data();
+ int offset = sizeof (DTA_Header) + 1; /* bytes 2-9 */
for (uint32_t i = 0; i < Invoker.size(); i++) {
cmdbuf[offset + i] = Invoker[i];
}
@@ -232,32 +260,30 @@ DtaCommand::getRespBuffer()
{
return respbuf;
}
+uint16_t
+DtaCommand::outputBufferSize() {
+ // if (MIN_BUFFER_LENGTH + 1 > bufferpos) return(MIN_BUFFER_LENGTH);
+ return (uint16_t)(((bufferpos + 511) / 512) * 512);
+}
void
DtaCommand::dumpCommand()
{
- OPALHeader * hdr = (OPALHeader *)cmdbuf;
- DtaHexDump(cmdbuf, SWAP32(hdr->cp.length) + sizeof(OPALComPacket));
+ DTA_Header * hdr = (DTA_Header *)cmdbuf;
+ DtaHexDump(cmdbuf, SWAP32(hdr->cp.length) + sizeof(DTA_ComPacketHeader));
}
void
DtaCommand::dumpResponse()
{
- OPALHeader *hdr = (OPALHeader *)respbuf;
- DtaHexDump(respbuf, SWAP32(hdr->cp.length) + sizeof(OPALComPacket));
-}
-uint16_t
-DtaCommand::outputBufferSize() {
-// if (MIN_BUFFER_LENGTH + 1 > bufferpos) return(MIN_BUFFER_LENGTH);
- if(bufferpos % 512)
- return(((uint16_t)(bufferpos / 512) + 1) * 512);
- else
- return((uint16_t)(bufferpos / 512) * 512);
+ DTA_Header *hdr = (DTA_Header *)respbuf;
+ DtaHexDump(respbuf, SWAP32(hdr->cp.length) + sizeof(DTA_ComPacketHeader));
}
void
DtaCommand::setcomID(uint16_t comID)
{
- OPALHeader * hdr;
- hdr = (OPALHeader *) cmdbuf;
LOG(D1) << "Entering DtaCommand::setcomID()";
+ LOG(D2) << "comID " << comID;
+ DTA_Header * hdr;
+ hdr = (DTA_Header *) cmdbuf;
hdr->cp.extendedComID[0] = ((comID & 0xff00) >> 8);
hdr->cp.extendedComID[1] = (comID & 0x00ff);
hdr->cp.extendedComID[2] = 0x00;
@@ -267,18 +293,20 @@ DtaCommand::setcomID(uint16_t comID)
void
DtaCommand::setTSN(uint32_t TSN)
{
- LOG(D1) << "Entering DtaCommand::setTSN()";
- OPALHeader * hdr;
- hdr = (OPALHeader *) cmdbuf;
+ LOG(D1) << "Entering DtaCommand::setTSN()";
+ LOG(D2) << "TSN is " << TSN;
+ DTA_Header * hdr;
+ hdr = (DTA_Header *) cmdbuf;
hdr->pkt.TSN = TSN;
}
void
DtaCommand::setHSN(uint32_t HSN)
{
- LOG(D1) << "Entering DtaCommand::setHSN()";
- OPALHeader * hdr;
- hdr = (OPALHeader *) cmdbuf;
+ LOG(D1) << "Entering DtaCommand::setHSN()";
+ LOG(D2) << "HSN is " << HSN;
+ DTA_Header * hdr;
+ hdr = (DTA_Header *) cmdbuf;
hdr->pkt.HSN = HSN;
}
diff --git a/Common/DtaCommand.h b/Common/DtaCommand.h
index 35f7217e..869416ff 100644
--- a/Common/DtaCommand.h
+++ b/Common/DtaCommand.h
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
@@ -42,14 +42,14 @@ class DtaCommand {
public:
/** Default constructor, allocates the command and resonse buffers. */
DtaCommand();
- /** Constructor that initializes the incokingUid and method fields.
- * @param InvokingUid The UID used to call the SSC method
+ /** Constructor that initializes the incokingUid and method fields.
+ * @param InvokingUid The UID used to call the SSC method
* @param method The SSC method to be called
*/
DtaCommand(OPAL_UID InvokingUid, OPAL_METHOD method);
/** destructor frees the command and response buffers */
~DtaCommand();
- /** Add a Token to the bytstream of type OPAL_TOKEN. */
+ /** Add a Token to the bytstream of type OPAL_TOKEN. */
void addToken(OPAL_TOKEN token);
/** Add a Token to the bytstream of type OPL_SHORT ATOM. */
void addToken(OPAL_SHORT_ATOM token);
@@ -57,6 +57,7 @@ class DtaCommand {
void addToken(OPAL_TINY_ATOM token);
/** Add a Token to the bytstream of from the OPALUID array. */
void addToken(OPAL_UID token);
+ void addToken(OPAL_UID token, uint8_t factor);
/** Add a Token to the bytstream of type c-string */
void addToken(const char * bytestring);
/** Add a Token to the bytstream of type vector.
@@ -72,11 +73,11 @@ class DtaCommand {
/** Set the TPer session number to be used for the command. */
void setTSN(uint32_t TSN);
/** Add the required fields to the end of the bytestream. If EOD is true (default) the
- * EOD token and the method status list will be added to the end of the bytestream.
+ * EOD token and the method status list will be added to the end of the bytestream.
* Then the bytstram is padded to a 4-byte boundary if required and the length fields
* are populated in packet, subpacket and command packet.
- *
- * @param EOD a bool to signal that command requires the EOD and method status fields
+ *
+ * @param EOD a bool to signal that command requires the EOD and method status fields
*/
void complete(uint8_t EOD = 1);
/** Clears the command buffer and resets the the end of buffer pointer
@@ -85,32 +86,32 @@ class DtaCommand {
void reset();
/** Clears the command buffer and resets the the end of buffer pointer
* also initializes the invoker and method fields.
- *
+ *
* @param InvokingUid The UID used to call the SSC method
- * @param method The SSC method to be called
+ * @param method The SSC method to be called
*/
void reset(OPAL_UID InvokingUid, OPAL_METHOD method);
/** Clears the command buffer and resets the the end of buffer pointer
* also initializes the invoker and method fields.
* The invoker is passed as a vector this is used for the case
- * where the invoker is not an OPAL user, typically a table.
- *
- * @param InvokingUid The UID used to call the SSC method
- * @param method The SSC method to be called
+ * where the invoker is not an OPAL user, typically a table.
+ *
+ * @param InvokingUid The UID used to call the SSC method
+ * @param method The SSC method to be called
*/
void reset(OPAL_UID InvokingUid, vector method);
/** Clears the command buffer and resets the the end of buffer pointer
* also initializes the invoker and method fields.
* Both the invoker and method are passed as a vector
- *
- * @param InvokingUid The UID used to call the SSC method
- * @param method The SSC method to be called
+ *
+ * @param InvokingUid The UID used to call the SSC method
+ * @param method The SSC method to be called
*/
void reset(vector InvokingUid, vector method);
/** Changes the invoker field.
* The invoker is passed as a vector this is used for the case
- * where the invoker is not an OPAL user, typically a table.
- *
+ * where the invoker is not an OPAL user, typically a table.
+ *
* @param Invoker The UID used to call the SSC method
*/
void changeInvokingUid(vector Invoker);
@@ -122,11 +123,13 @@ class DtaCommand {
uint16_t outputBufferSize();
private:
/** return a pointer to the command buffer */
+ uint8_t commandbuffer[MAX_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT]; /**< buffer allocation allow for 1k alignment */
void * getCmdBuffer();
+ size_t getCmdBufferSize() {return MAX_BUFFER_LENGTH;}
/** return a pointer to the response buffer. */
+ uint8_t responsebuffer[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT]; /**< buffer allocation allow for 1k alignment */
void * getRespBuffer();
- uint8_t commandbuffer[MAX_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT]; /**< buffer allocation allow for 1k alignment */
- uint8_t responsebuffer[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT]; /**< buffer allocation allow for 1k alignment */
+ size_t getRespBufferSize() {return MIN_BUFFER_LENGTH;}
uint8_t *cmdbuf; /**< Pointer to the command buffer */
uint8_t *respbuf; /**< pointer to the response buffer */
uint32_t bufferpos = 0; /**< position of the next byte in the command buffer */
diff --git a/Common/DtaDev.cpp b/Common/DtaDev.cpp
index 0346acf4..bb948cd4 100644
--- a/Common/DtaDev.cpp
+++ b/Common/DtaDev.cpp
@@ -1,37 +1,40 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
-This file is part of sedutil.
+ 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 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.
+ 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 .
+ You should have received a copy of the GNU General Public License
+ along with sedutil. If not, see .
- * C:E********************************************************************** */
+ * C:E********************************************************************** */
/** Base device class.
* An OS port must create a subclass of this class
- * implementing sendcmd, osmsSleep and identify
+ * implementing sendcmd, osmsSleep and identify
* specific to the IO requirements of that OS
*/
#include "os.h"
#include
+#include
#include
#include
#include "DtaOptions.h"
#include "DtaDev.h"
#include "DtaStructures.h"
-#include "DtaConstants.h"
#include "DtaEndianFixup.h"
#include "DtaHexDump.h"
+#include "DtaSession.h"
+#include "DtaCommand.h"
+
using namespace std;
@@ -44,259 +47,433 @@ DtaDev::DtaDev()
DtaDev::~DtaDev()
{
}
+
+uint8_t DtaDev::isRuby()
+{
+ LOG(D2) << "Entering DtaDev::isRuby " << (uint16_t)disk_info.RUBY;
+ return disk_info.RUBY;
+}
+
+uint8_t DtaDev::isFIPS()
+{
+ LOG(D2) << "Entering DtaDev::isFIPS " << (uint16_t)disk_info.fips;
+ return disk_info.fips;
+}
+
+uint8_t DtaDev::isOpalite()
+{
+ LOG(D2) << "Entering DtaDev::isOpalite " << (uint16_t) disk_info.OPALITE;
+ return disk_info.OPALITE;
+}
+uint8_t DtaDev::isPyrite2()
+{
+ LOG(D2) << "Entering DtaDev::isPyrite2 " << (uint16_t)disk_info.PYRITE2;
+ return disk_info.PYRITE2;
+}
+uint8_t DtaDev::isPyrite()
+{
+ LOG(D2) << "Entering DtaDev::isPyrite " << (uint16_t) disk_info.PYRITE;
+ return disk_info.PYRITE;
+}
+uint8_t DtaDev::isOpal2_minor_v()
+{
+ LOG(D2) << "Entering DtaDev::isOpal2_minor " << (uint16_t)disk_info.OPAL20_minor_v;
+ return disk_info.OPAL20_minor_v;
+}
+uint8_t DtaDev::isOpal2_version()
+{
+ LOG(D2) << "Entering DtaDev::isOpal2_version " << (uint16_t)disk_info.OPAL20_version;
+ return disk_info.OPAL20_version;
+}
uint8_t DtaDev::isOpal2()
{
- LOG(D1) << "Entering DtaDev::isOpal2 " << (uint16_t) disk_info.OPAL20;
- return disk_info.OPAL20;
+ LOG(D2) << "Entering DtaDev::isOpal2 " << (uint16_t) disk_info.OPAL20;
+ return disk_info.OPAL20;
}
uint8_t DtaDev::isOpal1()
{
- LOG(D1) << "Entering DtaDev::isOpal1() " << (uint16_t)disk_info.OPAL10;
- return disk_info.OPAL10;
+ LOG(D2) << "Entering DtaDev::isOpal1() " << (uint16_t)disk_info.OPAL10;
+ return disk_info.OPAL10;
}
uint8_t DtaDev::isEprise()
{
- LOG(D1) << "Entering DtaDev::isEprise " << (uint16_t) disk_info.Enterprise;
- return disk_info.Enterprise;
+ LOG(D2) << "Entering DtaDev::isEprise " << (uint16_t) disk_info.Enterprise;
+ return disk_info.Enterprise;
}
-
uint8_t DtaDev::isAnySSC()
{
- LOG(D1) << "Entering DtaDev::isAnySSC " << (uint16_t)disk_info.ANY_OPAL_SSC;
- return disk_info.ANY_OPAL_SSC;
+ LOG(D2) << "Entering DtaDev::isAnySSC " << (uint16_t)disk_info.ANY_OPAL_SSC;
+ return disk_info.ANY_OPAL_SSC;
}
uint8_t DtaDev::isPresent()
{
- LOG(D1) << "Entering DtaDev::isPresent() " << (uint16_t) isOpen;
- return isOpen;
+ LOG(D2) << "Entering DtaDev::isPresent() " << (uint16_t) isOpen;
+ return isOpen;
+}
+uint8_t DtaDev::isNVMEbus()
+{
+ LOG(D2) << "Entering DtaDev::isNVMEbus() " << (uint16_t)isNVME;
+ return isNVME;
}
uint8_t DtaDev::MBREnabled()
{
- LOG(D1) << "Entering DtaDev::MBRENabled" << (uint16_t)disk_info.Locking_MBREnabled;
- return disk_info.Locking_MBREnabled;
+ LOG(D2) << "Entering DtaDev::MBRENabled" << (uint16_t)disk_info.Locking_MBREnabled;
+ return disk_info.Locking_MBREnabled;
}
uint8_t DtaDev::MBRDone()
{
- LOG(D1) << "Entering DtaDev::MBRDone" << (uint16_t)disk_info.Locking_MBRDone;
- return disk_info.Locking_MBRDone;
+ LOG(D2) << "Entering DtaDev::MBRDone" << (uint16_t)disk_info.Locking_MBRDone;
+ return disk_info.Locking_MBRDone;
}
uint8_t DtaDev::Locked()
{
- LOG(D1) << "Entering DtaDev::Locked" << (uint16_t)disk_info.Locking_locked;
- return disk_info.Locking_locked;
+ LOG(D2) << "Entering DtaDev::Locked" << (uint16_t)disk_info.Locking_locked;
+ return disk_info.Locking_locked;
}
uint8_t DtaDev::LockingEnabled()
{
- LOG(D1) << "Entering DtaDev::LockingEnabled" << (uint16_t)disk_info.Locking_lockingEnabled;
- return disk_info.Locking_lockingEnabled;
+ LOG(D2) << "Entering DtaDev::LockingEnabled" << (uint16_t)disk_info.Locking_lockingEnabled;
+ return disk_info.Locking_lockingEnabled;
}
char *DtaDev::getFirmwareRev()
{
- return (char *)&disk_info.firmwareRev;
+ return (char *)&disk_info.firmwareRev;
}
char *DtaDev::getModelNum()
{
- return (char *)&disk_info.modelNum;
+ return (char *)&disk_info.modelNum;
}
char *DtaDev::getSerialNum()
{
- return (char *)&disk_info.serialNum;
+ return (char *)&disk_info.serialNum;
+}
+vectorDtaDev::getPasswordSalt()
+{
+ const uint8_t * b=disk_info.passwordSalt;
+ return vector(b,b+sizeof(disk_info.passwordSalt));
}
DTA_DEVICE_TYPE DtaDev::getDevType()
- {
- return disk_info.devType;
- }
-void DtaDev::discovery0()
{
- LOG(D1) << "Entering DtaDev::discovery0()";
- uint8_t lastRC;
- void * d0Response = NULL;
- uint8_t * epos, *cpos;
- Discovery0Header * hdr;
- Discovery0Features * body;
- d0Response = discovery0buffer + IO_BUFFER_ALIGNMENT;
- d0Response = (void *)((uintptr_t)d0Response & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
- memset(d0Response, 0, MIN_BUFFER_LENGTH);
- if ((lastRC = sendCmd(IF_RECV, 0x01, 0x0001, d0Response, MIN_BUFFER_LENGTH)) != 0) {
- LOG(D) << "Send D0 request to device failed " << (uint16_t)lastRC;
- return;
- }
+ return disk_info.devType;
+}
+
+char *DtaDev::getVendorID()
+{
+ return (char *)&disk_info.vendorID;
+}
+
+char *DtaDev::getManufacturerName()
+{
+ return (char *)&disk_info.manufacturerName;
+}
+
+vectorDtaDev::getWorldWideName()
+{
+ const uint8_t * b=disk_info.worldWideName;
+ return vector(b,b+sizeof(disk_info.worldWideName));
+}
+
+bool DtaDev::isWorldWideNameSynthetic()
+{
+ return 0!=disk_info.worldWideNameIsSynthetic;
+}
- epos = cpos = (uint8_t *) d0Response;
- hdr = (Discovery0Header *) d0Response;
- LOG(D3) << "Dumping D0Response";
- IFLOG(D3) DtaHexDump(hdr, SWAP32(hdr->length));
- epos = epos + SWAP32(hdr->length);
- cpos = cpos + 48; // TODO: check header version
-
- do {
- body = (Discovery0Features *) cpos;
- switch (SWAP16(body->TPer.featureCode)) { /* could use of the structures here is a common field */
- case FC_TPER: /* TPer */
- disk_info.TPer = 1;
- disk_info.TPer_ACKNACK = body->TPer.acknack;
- disk_info.TPer_async = body->TPer.async;
- disk_info.TPer_bufferMgt = body->TPer.bufferManagement;
- disk_info.TPer_comIDMgt = body->TPer.comIDManagement;
- disk_info.TPer_streaming = body->TPer.streaming;
- disk_info.TPer_sync = body->TPer.sync;
- break;
- case FC_LOCKING: /* Locking*/
- disk_info.Locking = 1;
- disk_info.Locking_locked = body->locking.locked;
- disk_info.Locking_lockingEnabled = body->locking.lockingEnabled;
- disk_info.Locking_lockingSupported = body->locking.lockingSupported;
- disk_info.Locking_MBRDone = body->locking.MBRDone;
- disk_info.Locking_MBREnabled = body->locking.MBREnabled;
- disk_info.Locking_mediaEncrypt = body->locking.mediaEncryption;
- break;
- case FC_GEOMETRY: /* Geometry Features */
- disk_info.Geometry = 1;
- disk_info.Geometry_align = body->geometry.align;
- disk_info.Geometry_alignmentGranularity = SWAP64(body->geometry.alignmentGranularity);
- disk_info.Geometry_logicalBlockSize = SWAP32(body->geometry.logicalBlockSize);
- disk_info.Geometry_lowestAlignedLBA = SWAP64(body->geometry.lowestAlighedLBA);
- break;
- case FC_ENTERPRISE: /* Enterprise SSC */
- disk_info.Enterprise = 1;
- disk_info.ANY_OPAL_SSC = 1;
- disk_info.Enterprise_rangeCrossing = body->enterpriseSSC.rangeCrossing;
- disk_info.Enterprise_basecomID = SWAP16(body->enterpriseSSC.baseComID);
- disk_info.Enterprise_numcomID = SWAP16(body->enterpriseSSC.numberComIDs);
- break;
- case FC_OPALV100: /* Opal V1 */
- disk_info.OPAL10 = 1;
- disk_info.ANY_OPAL_SSC = 1;
- disk_info.OPAL10_basecomID = SWAP16(body->opalv100.baseComID);
- disk_info.OPAL10_numcomIDs = SWAP16(body->opalv100.numberComIDs);
- break;
- case FC_SINGLEUSER: /* Single User Mode */
- disk_info.SingleUser = 1;
- disk_info.SingleUser_all = body->singleUserMode.all;
- disk_info.SingleUser_any = body->singleUserMode.any;
- disk_info.SingleUser_policy = body->singleUserMode.policy;
- disk_info.SingleUser_lockingObjects = SWAP32(body->singleUserMode.numberLockingObjects);
- break;
- case FC_DATASTORE: /* Datastore Tables */
- disk_info.DataStore = 1;
- disk_info.DataStore_maxTables = SWAP16(body->datastore.maxTables);
- disk_info.DataStore_maxTableSize = SWAP32(body->datastore.maxSizeTables);
- disk_info.DataStore_alignment = SWAP32(body->datastore.tableSizeAlignment);
- break;
- case FC_OPALV200: /* OPAL V200 */
- disk_info.OPAL20 = 1;
- disk_info.ANY_OPAL_SSC = 1;
- disk_info.OPAL20_basecomID = SWAP16(body->opalv200.baseCommID);
- disk_info.OPAL20_initialPIN = body->opalv200.initialPIN;
- disk_info.OPAL20_revertedPIN = body->opalv200.revertedPIN;
- disk_info.OPAL20_numcomIDs = SWAP16(body->opalv200.numCommIDs);
- disk_info.OPAL20_numAdmins = SWAP16(body->opalv200.numlockingAdminAuth);
- disk_info.OPAL20_numUsers = SWAP16(body->opalv200.numlockingUserAuth);
- disk_info.OPAL20_rangeCrossing = body->opalv200.rangeCrossing;
- break;
- default:
- if (0xbfff < (SWAP16(body->TPer.featureCode))) {
- // silently ignore vendor specific segments as there is no public doc on them
- disk_info.VendorSpecific += 1;
- }
- else {
- disk_info.Unknown += 1;
- LOG(D) << "Unknown Feature in Discovery 0 response " << std::hex << SWAP16(body->TPer.featureCode) << std::dec;
- /* should do something here */
- }
- break;
- }
- cpos = cpos + (body->TPer.length + 4);
- }
- while (cpos < epos);
+int DtaDev::TperReset()
+{
+ LOG(D2) << "Entering DtaDev::TperReset()";
+ int lastRC;
+ void * tpResponse = (void *)((((uintptr_t)discovery0buffer) +
+ (uintptr_t)IO_BUFFER_ALIGNMENT) & // 0x00002000 if e.g. 16384
+ (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1)); // ~0x00001FFF will be
+ // 0xFFFFE000 masking to alignment
+ memset(tpResponse, 0, MIN_BUFFER_LENGTH);
+ // TperReset ProtocolID=0x02 ComID=0x0004
+ if ((lastRC = sendCmd(IF_SEND, 0x02, 0x0004, tpResponse, 512)) != 0) { // 2048->512
+ LOG(D2) << "Send TperReset to device failed " << (uint16_t)lastRC;
+ return lastRC;
+ }
+ IFLOG(D2) DtaHexDump((char *)tpResponse,64);
+ return 0;
}
+
+/*
+ uint8_t DtaDev::STACK_Reset()
+ {
+ LOG(D2) << "Entering DtaDev::STACK_Reset()";
+ uint8_t lastRC;
+ void * STACKResponse = NULL;
+ STACKResponse = discovery0buffer + IO_BUFFER_ALIGNMENT;
+ STACKResponse = (void *)((uintptr_t)STACKResponse & (uintptr_t)~(IO_BUFFER_ALIGNMENT - 1));
+ memset(STACKResponse, 0, IO_BUFFER_LENGTH);
+ // STACK_RESET
+ if ((lastRC = sendCmd(IF_SEND, 0x02, 0x0004, STACKResponse, 512)) != 0) { // 2048->512
+ LOG(D2) << "Send STACK_Reset to device failed " << (uint16_t)lastRC;
+ return lastRC;
+ }
+ DtaHexDump((char *)STACKResponse, 64);
+ return 0;
+ }
+
+*/
+
void DtaDev::puke()
{
- LOG(D1) << "Entering DtaDev::puke()";
- /* IDENTIFY */
- cout << endl << dev << (disk_info.devType == DEVICE_TYPE_ATA ? " ATA " :
- disk_info.devType == DEVICE_TYPE_SAS ? " SAS " :
- disk_info.devType == DEVICE_TYPE_USB ? " USB " :
- disk_info.devType == DEVICE_TYPE_NVME ? " NVMe " :
- " OTHER ");
- cout << disk_info.modelNum << " " << disk_info.firmwareRev << " " << disk_info.serialNum << endl;
- /* TPer */
- if (disk_info.TPer) {
- cout << "TPer function (" << HEXON(4) << FC_TPER << HEXOFF << ")" << std::endl;
- cout << " ACKNAK = " << (disk_info.TPer_ACKNACK ? "Y, " : "N, ")
- << "ASYNC = " << (disk_info.TPer_async ? "Y, " : "N. ")
- << "BufferManagement = " << (disk_info.TPer_bufferMgt ? "Y, " : "N, ")
- << "comIDManagement = " << (disk_info.TPer_comIDMgt ? "Y, " : "N, ")
- << "Streaming = " << (disk_info.TPer_streaming ? "Y, " : "N, ")
- << "SYNC = " << (disk_info.TPer_sync ? "Y" : "N")
- << std::endl;
- }
- if (disk_info.Locking) {
-
- cout << "Locking function (" << HEXON(4) << FC_LOCKING << HEXOFF << ")" << std::endl;
- cout << " Locked = " << (disk_info.Locking_locked ? "Y, " : "N, ")
- << "LockingEnabled = " << (disk_info.Locking_lockingEnabled ? "Y, " : "N, ")
- << "LockingSupported = " << (disk_info.Locking_lockingSupported ? "Y, " : "N, ");
- cout << "MBRDone = " << (disk_info.Locking_MBRDone ? "Y, " : "N, ")
- << "MBREnabled = " << (disk_info.Locking_MBREnabled ? "Y, " : "N, ")
- << "MediaEncrypt = " << (disk_info.Locking_mediaEncrypt ? "Y" : "N")
- << std::endl;
- }
- if (disk_info.Geometry) {
-
- cout << "Geometry function (" << HEXON(4) << FC_GEOMETRY << HEXOFF << ")" << std::endl;
- cout << " Align = " << (disk_info.Geometry_align ? "Y, " : "N, ")
- << "Alignment Granularity = " << disk_info.Geometry_alignmentGranularity
- << " (" << // display bytes
- (disk_info.Geometry_alignmentGranularity *
- disk_info.Geometry_logicalBlockSize)
- << ")"
- << ", Logical Block size = " << disk_info.Geometry_logicalBlockSize
- << ", Lowest Aligned LBA = " << disk_info.Geometry_lowestAlignedLBA
- << std::endl;
- }
- if (disk_info.Enterprise) {
- cout << "Enterprise function (" << HEXON(4) << FC_ENTERPRISE << HEXOFF << ")" << std::endl;
- cout << " Range crossing = " << (disk_info.Enterprise_rangeCrossing ? "Y, " : "N, ")
- << "Base comID = " << HEXON(4) << disk_info.Enterprise_basecomID
- << ", comIDs = " << disk_info.Enterprise_numcomID << HEXOFF
- << std::endl;
- }
- if (disk_info.OPAL10) {
- cout << "Opal V1.0 function (" << HEXON(4) << FC_OPALV100 << HEXOFF << ")" << std::endl;
- cout << "Base comID = " << HEXON(4) << disk_info.OPAL10_basecomID << HEXOFF
- << ", comIDs = " << disk_info.OPAL10_numcomIDs
- << std::endl;
- }
- if (disk_info.SingleUser) {
- cout << "SingleUser function (" << HEXON(4) << FC_SINGLEUSER << HEXOFF << ")" << std::endl;
- cout << " ALL = " << (disk_info.SingleUser_all ? "Y, " : "N, ")
- << "ANY = " << (disk_info.SingleUser_any ? "Y, " : "N, ")
- << "Policy = " << (disk_info.SingleUser_policy ? "Y, " : "N, ")
- << "Locking Objects = " << (disk_info.SingleUser_lockingObjects)
- << std::endl;
- }
- if (disk_info.DataStore) {
- cout << "DataStore function (" << HEXON(4) << FC_DATASTORE << HEXOFF << ")" << std::endl;
- cout << " Max Tables = " << disk_info.DataStore_maxTables
- << ", Max Size Tables = " << disk_info.DataStore_maxTableSize
- << ", Table size alignment = " << disk_info.DataStore_alignment
- << std::endl;
- }
-
- if (disk_info.OPAL20) {
- cout << "OPAL 2.0 function (" << HEXON(4) << FC_OPALV200 << ")" << HEXOFF << std::endl;
- cout << " Base comID = " << HEXON(4) << disk_info.OPAL20_basecomID << HEXOFF;
- cout << ", Initial PIN = " << HEXON(2) << static_cast(disk_info.OPAL20_initialPIN) << HEXOFF;
- cout << ", Reverted PIN = " << HEXON(2) << static_cast(disk_info.OPAL20_revertedPIN) << HEXOFF;
- cout << ", comIDs = " << disk_info.OPAL20_numcomIDs;
- cout << std::endl;
- cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
- cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
- cout << ", Range Crossing = " << (disk_info.OPAL20_rangeCrossing ? "Y" : "N");
- cout << std::endl;
- }
- if (disk_info.Unknown)
- cout << "**** " << (uint16_t)disk_info.Unknown << " **** Unknown function codes IGNORED " << std::endl;
+ LOG(D2) << "Entering DtaDev::puke()";
+ /* IDENTIFY */
+ const char * devType =
+ disk_info.devType == DEVICE_TYPE_ATA ? " ATA "
+ : disk_info.devType == DEVICE_TYPE_SAS ? " SAS "
+ : disk_info.devType == DEVICE_TYPE_USB ? " USB "
+ : disk_info.devType == DEVICE_TYPE_NVME ? " NVMe "
+ : " OTHER ";
+ cout << endl << dev << devType << " " << disk_info.modelNum << " " << disk_info.firmwareRev << " " << disk_info.serialNum;
+ IFLOG(D) {
+ char WWN[19]=" "; // 16 blanks as placeholder if missing
+ uint8_t (&wwn)[8] = disk_info.worldWideName;
+ if (__is_not_all_NULs(wwn, sizeof(wwn))) {
+ snprintf(WWN, 19, "%02X%02X%02X%02X%02X%02X%02X%02X %c",
+ wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7],
+ disk_info.worldWideNameIsSynthetic ? '*' : ' ');
+ }
+ cout << " " << WWN
+ << " " << disk_info.vendorID
+ << " " << disk_info.manufacturerName;
+ }
+ cout << endl;
+
+ /* TPer */
+ if (disk_info.TPer) {
+ cout << "TPer function (" << HEXON(4) << FC_TPER << HEXOFF << ")" << std::endl;
+ cout << " ACKNAK = " << (disk_info.TPer_ACKNACK ? "Y, " : "N, ")
+ << "ASYNC = " << (disk_info.TPer_async ? "Y, " : "N. ")
+ << "BufferManagement = " << (disk_info.TPer_bufferMgt ? "Y, " : "N, ")
+ << "comIDManagement = " << (disk_info.TPer_comIDMgt ? "Y, " : "N, ")
+ << "Streaming = " << (disk_info.TPer_streaming ? "Y, " : "N, ")
+ << "SYNC = " << (disk_info.TPer_sync ? "Y" : "N")
+ << std::endl;
+ }
+ if (disk_info.Locking) {
+
+ cout << "Locking function (" << HEXON(4) << FC_LOCKING << HEXOFF << ")" << std::endl;
+ cout << " Locked = " << (disk_info.Locking_locked ? "Y, " : "N, ")
+ << "LockingEnabled = " << (disk_info.Locking_lockingEnabled ? "Y, " : "N, ")
+ << "MBR shadowing Not Supported = " << (disk_info.Locking_MBRshadowingNotSupported ? "Y, " : "N, ")
+ << "MBRDone = " << (disk_info.Locking_MBRDone ? "Y, " : "N, ")
+ << "MBREnabled = " << (disk_info.Locking_MBREnabled ? "Y, " : "N, ")
+ << "MediaEncrypt = " << (disk_info.Locking_mediaEncrypt ? "Y" : "N")
+ << std::endl;
+ }
+ if (disk_info.Geometry) {
+
+ cout << "Geometry function (" << HEXON(4) << FC_GEOMETRY << HEXOFF << ")" << std::endl;
+ cout << " Align = " << (disk_info.Geometry_align ? "Y, " : "N, ")
+ << "Alignment Granularity = " << disk_info.Geometry_alignmentGranularity
+ << " (" << // display bytes
+ (disk_info.Geometry_alignmentGranularity *
+ disk_info.Geometry_logicalBlockSize)
+ << ")"
+ << ", Logical Block size = " << disk_info.Geometry_logicalBlockSize
+ << ", Lowest Aligned LBA = " << disk_info.Geometry_lowestAlignedLBA
+ << std::endl;
+ }
+ if (disk_info.Enterprise) {
+ cout << "Enterprise function (" << HEXON(4) << FC_ENTERPRISE << HEXOFF << ")" << std::endl;
+ cout << " Range crossing = " << (disk_info.Enterprise_rangeCrossing ? "Y, " : "N, ")
+ << "Base comID = " << HEXON(4) << disk_info.Enterprise_basecomID
+ << ", comIDs = " << disk_info.Enterprise_numcomID << HEXOFF
+ << std::endl;
+ }
+ if (disk_info.OPAL10) {
+ cout << "Opal V1.0 function (" << HEXON(4) << FC_OPALV100 << HEXOFF << ")" << std::endl;
+ cout << "Base comID = " << HEXON(4) << disk_info.OPAL10_basecomID << HEXOFF
+ << ", comIDs = " << disk_info.OPAL10_numcomIDs
+ << std::endl;
+ }
+ if (disk_info.SingleUser) {
+ cout << "SingleUser function (" << HEXON(4) << FC_SINGLEUSER << HEXOFF << ")" << std::endl;
+ cout << " ALL = " << (disk_info.SingleUser_all ? "Y, " : "N, ")
+ << "ANY = " << (disk_info.SingleUser_any ? "Y, " : "N, ")
+ << "Policy = " << (disk_info.SingleUser_policy ? "Y, " : "N, ")
+ << "Locking Objects = " << (disk_info.SingleUser_lockingObjects)
+ << std::endl;
+ }
+ if (disk_info.DataStore) {
+ cout << "DataStore function (" << HEXON(4) << FC_DATASTORE << HEXOFF << ")" << std::endl;
+ cout << " Max Tables = " << disk_info.DataStore_maxTables
+ << ", Max Size Tables = " << disk_info.DataStore_maxTableSize
+ << ", Table size alignment = " << disk_info.DataStore_alignment
+ << std::endl;
+ }
+
+ if (disk_info.OPAL20) {
+ cout << "OPAL 2." << ((disk_info.OPAL20_version -1) & 0xf) << " function (" << HEXON(4) << FC_OPALV200 << ")" << HEXOFF << std::endl;
+ cout << " Base comID = " << HEXON(4) << disk_info.OPAL20_basecomID << HEXOFF;
+ cout << ", Initial PIN = " << HEXON(2) << static_cast(disk_info.OPAL20_initialPIN) << HEXOFF;
+ cout << ", Reverted PIN = " << HEXON(2) << static_cast(disk_info.OPAL20_revertedPIN) << HEXOFF;
+ cout << ", comIDs = " << disk_info.OPAL20_numcomIDs;
+ cout << std::endl;
+ cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
+ cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
+ cout << ", Range Crossing = " << (disk_info.OPAL20_rangeCrossing ? "Y" : "N");
+ cout << std::endl;
+ }
+ if (disk_info.OPALITE) {
+ cout << "OPALITE 1." << ((disk_info.OPALITE_version & 0xf) - 1) << " function (" << HEXON(4) << FC_OPALITE << ")" << HEXOFF << std::endl;
+ cout << " Base comID = " << HEXON(4) << disk_info.OPALITE_basecomID << HEXOFF;
+ cout << ", Initial PIN = " << HEXON(2) << disk_info.OPALITE_initialPIN << HEXOFF;
+ cout << ", Reverted PIN = " << HEXON(2) << disk_info.OPALITE_revertedPIN << HEXOFF;
+ cout << ", comIDs = " << disk_info.OPALITE_numcomIDs;
+ cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
+ cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
+ cout << std::endl;
+ }
+ if (disk_info.PYRITE) {
+ cout << "PYRITE 1." << ((disk_info.PYRITE_version & 0xf) -1) << " function (" << HEXON(4) << FC_PYRITE << ")" << HEXOFF << std::endl;
+ cout << " Base comID = " << HEXON(4) << disk_info.PYRITE_basecomID << HEXOFF;
+ cout << ", Initial PIN = " << HEXON(2) << disk_info.PYRITE_initialPIN << HEXOFF;
+ cout << ", Reverted PIN = " << HEXON(2) << disk_info.PYRITE_revertedPIN << HEXOFF;
+ cout << ", comIDs = " << disk_info.PYRITE_numcomIDs;
+ cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
+ cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
+ cout << std::endl;
+ }
+ if (disk_info.PYRITE2) {
+ cout << "PYRITE 2." << ((disk_info.PYRITE2_version & 0xf) - 1) << " function (" << HEXON(4) << FC_PYRITE << ")" << HEXOFF << std::endl;
+ cout << " Base comID = " << HEXON(4) << disk_info.PYRITE2_basecomID << HEXOFF;
+ cout << ", Initial PIN = " << HEXON(2) << disk_info.PYRITE2_initialPIN << HEXOFF;
+ cout << ", Reverted PIN = " << HEXON(2) << disk_info.PYRITE2_revertedPIN << HEXOFF;
+ cout << ", comIDs = " << disk_info.PYRITE2_numcomIDs;
+ cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
+ cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
+ cout << std::endl;
+ }
+ if (disk_info.RUBY) {
+ cout << "RUBY 1." << ((disk_info.RUBY_version & 0xf) - 1) << " function (" << HEXON(4) << FC_RUBY << ")" << HEXOFF << std::endl;
+ cout << " Base comID = " << HEXON(4) << disk_info.RUBY_basecomID << HEXOFF;
+ cout << ", Initial PIN = " << HEXON(2) << disk_info.RUBY_initialPIN << HEXOFF;
+ cout << ", Reverted PIN = " << HEXON(2) << disk_info.RUBY_revertedPIN << HEXOFF;
+ cout << ", comIDs = " << disk_info.RUBY_numcomIDs;
+ cout << " Locking Admins = " << disk_info.OPAL20_numAdmins;
+ cout << ", Locking Users = " << disk_info.OPAL20_numUsers;
+ cout << std::endl;
+ }
+ if (disk_info.BlockSID) {
+ cout << "BlockSID function (" << HEXON(4) << FC_BlockSID << ")" << HEXOFF << std::endl;
+ cout << " BlockSIDState = " << (disk_info.BlockSID_BlockSIDState ? "Y" : "N" );
+ cout << ", SIDvalueState = " << (disk_info.BlockSID_SIDvalueState? "1" : "0");
+ cout << ", HardReset = " << (disk_info.BlockSID_HardReset? "1" : "0") ;
+ cout << std::endl;
+ }
+ if (disk_info.DataRemoval) {
+ cout << "DataRemoval 1." << ((disk_info.DataRemoval_version & 0xf) - 1) << " function (" << HEXON(4) << FC_DataRemoval << ")" << HEXOFF << std::endl;
+ cout << " DataRemoval OperationProcessing " << HEXON(2) << disk_info.DataRemoval_OperationProcessing << HEXOFF;
+ cout << ", DataRemoval Machanisim " << HEXON(2) << disk_info.DataRemoval_Mechanism << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 5 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit5 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit5 << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 4 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit4 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit4 << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 3 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit3 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit3 << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 2 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit2 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit2 << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 1 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit1 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit1 << HEXOFF << std::endl;
+ cout << " DataRemoval TimeFormat Bit 0 : " << HEXON(2) << disk_info.DataRemoval_TimeFormat_Bit0 << " " << HEXON(4) << disk_info.DataRemoval_Time_Bit0 << HEXOFF << std::endl;
+ }
+
+
+
+ if (disk_info.Unknown)
+ cout << "**** " << (uint16_t)disk_info.Unknown << " **** Unknown function codes IGNORED " << std::endl;
+}
+
+uint8_t DtaDev::WithSession(std::functionstartSessionFn,
+ std::functionsessionBodyFn) {
+ session = new DtaSession(this);
+ if (NULL == session) {
+ LOG(E) << "Unable to create session object " << dev;
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+
+
+ uint8_t lastRC = startSessionFn();
+
+ if (lastRC == 0) {
+ lastRC = sessionBodyFn();
+ }
+
+ delete session;
+ return lastRC;
+
+}
+
+uint8_t DtaDev::WithSessionCommand(std::functionstartSessionFn,
+ std::functioncommandWriterFn) {
+ return WithSession(startSessionFn, [this, commandWriterFn]()->uint8_t{
+ DtaCommand *command = new DtaCommand();
+ if (NULL == command) {
+ LOG(E) << "Unable to create command object " << dev;
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ commandWriterFn(command);
+ uint8_t rc = session->sendCommand(command, response);
+ delete command;
+ return rc;
+ });
+}
+
+
+
+
+/** start an anonymous session
+ * @param SP the Security Provider to start the session with */
+uint8_t DtaDev::start(OPAL_UID SP){
+ if (session == NULL)
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ return session->start(SP);
+}
+
+
+/** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ */
+uint8_t DtaDev::start(OPAL_UID SP, char * password, OPAL_UID SignAuthority){
+ if (session == NULL)
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ return session->start(SP, password, SignAuthority);
+}
+
+
+
+/** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param HostChallenge the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ */
+uint8_t DtaDev::start(OPAL_UID SP, vector HostChallenge, OPAL_UID SignAuthority){
+ if (session == NULL)
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ return session->start(SP, HostChallenge, SignAuthority);
+}
+
+
+/** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * */
+uint8_t DtaDev::start(OPAL_UID SP, char * password, vector SignAuthority){
+ if (session == NULL)
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ return session->start(SP, password, SignAuthority);
+}
+
+
+/** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param HostChallenge the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * */
+uint8_t DtaDev::start(OPAL_UID SP, vector HostChallenge, vector SignAuthority){
+ if (session == NULL)
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ return session->start(SP, HostChallenge, SignAuthority);
}
diff --git a/Common/DtaDev.h b/Common/DtaDev.h
index 473f7bd0..091596ca 100644
--- a/Common/DtaDev.h
+++ b/Common/DtaDev.h
@@ -1,298 +1,660 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
-This file is part of sedutil.
+ 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 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.
+ 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 .
+ You should have received a copy of the GNU General Public License
+ along with sedutil. If not, see .
- * C:E********************************************************************** */
+ * C:E********************************************************************** */
#pragma once
+#include
+#include
+using namespace std;
+
+#include "os.h"
+
#include "DtaStructures.h"
#include "DtaLexicon.h"
-#include
-#include "DtaOptions.h"
#include "DtaResponse.h"
+#include "DtaConstants.h"
+#include "DtaOptions.h"
+
class DtaCommand;
class DtaSession;
-using namespace std;
-/** Base class for a disk device.
+#define __unimplemented__ {throw __PRETTY_FUNCTION__;}
+
+/** Base class for a disk^H^H^H^H device.
* This is a virtual base class defining the minimum functionality of device
- * object. The methods defined here are called by other parts of the program
+ * object. The methods defined here are called by other parts of the program
* so must be present in all devices
*/
class DtaDev {
public:
- /** Default constructor, does nothing */
- DtaDev();
- /** Default destructor, does nothing*/
- virtual ~DtaDev();
- /** Does the device conform to the OPAL 2.0 SSC */
- uint8_t isOpal2();
- /** Does the device conform to the OPAL 1.0 SSC */
- uint8_t isOpal1();
- /** Does the device conform to the OPAL Enterprise SSC */
- uint8_t isEprise();
- /** Does the device conform to ANY TCG storage SSC */
- uint8_t isAnySSC();
- /** Is the MBREnabled flag set */
- uint8_t MBREnabled();
- /** Is the MBRDone flag set */
- uint8_t MBRDone();
- /** Is the Locked flag set */
- uint8_t Locked();
- /** Is the Locking SP enabled */
- uint8_t LockingEnabled();
- /** Is there an OS disk represented by this object */
- uint8_t isPresent();
- /** Returns the Firmware revision reported by the identify command */
- char *getFirmwareRev();
- /** Returns the Model Number reported by the Identify command */
- char *getModelNum();
- /** Returns the Serial Number reported by the Identify command */
- char *getSerialNum();
- /* What type of disk attachment is used */
- DTA_DEVICE_TYPE getDevType();
- /** displays the information returned by the Discovery 0 reply */
- virtual void puke();
-
- /** Decode the Discovery 0 response. Scans the D0 response and creates a structure
- * that can be queried later as required.This code also takes care of
- * the endianess conversions either via a bitswap in the structure or executing
- * a macro when the input buffer is read.
- */
- void discovery0();
-
- /*
- * virtual methods required in the OS specific
- * device class
- */
- /** OS specific initialization.
- * This function should perform the necessary authority and environment checking
- * to allow proper functioning of the program, open the device, perform an ATA
- * identify, add the fields from the identify response to the disk info structure
- * and if the device is an ATA device perform a call to Discovery0() to complete
- * the disk_info structure
- * @param devref character representation of the device is standard OS lexicon
- */
- virtual void init(const char * devref) = 0;
- /** OS specific method to send an ATA command to the device
- * @param cmd ATA command to be sent to the device
- * @param protocol security protocol to be used in the command
- * @param comID communications ID to be used
- * @param buffer input/output buffer
- * @param bufferlen length of the input/output buffer
- */
- virtual uint8_t sendCmd(ATACOMMAND cmd, uint8_t protocol, uint16_t comID,
- void * buffer, uint32_t bufferlen) = 0;
- /** OS specific command to Wait for specified number of milliseconds
- * @param milliseconds number of milliseconds to wait
- */
- virtual void osmsSleep(uint32_t milliseconds) = 0;
- /** OS specific routine to send an ATA identify to the device */
- virtual void identify(OPAL_DiskInfo& disk_info) = 0;
- /** OS specific routine to get size of the device */
- virtual unsigned long long getSize() = 0;
- /*
- * virtual functions required to be implemented
- * because they are called by sedutil.cpp
- */
- /** 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
- */
- virtual uint8_t initialSetup(char * password) = 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
- * @param length length (in blocks) for locking range
- * @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;
- /** 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
- */
- virtual uint8_t setSIDPassword(char * oldpassword, char * newpassword,
- uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) = 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
- */
- virtual uint8_t setPassword(char * password, char * userid, char * newpassword) = 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;
- /** 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
- */
- virtual uint8_t loadPBA(char * password, char * filename) = 0;
- /** Change the locking state of a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param lockingstate the locking state to set
- * @param Admin1Password password of administrative authority for locking range
- */
- virtual uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
- char * Admin1Password) = 0;
- /** Change the locking state of a locking range in Single User Mode
- * @param lockingrange The number of the locking range (0 = global)
- * @param lockingstate the locking state to set
- * @param password password of user authority for the locking range
- */
- virtual uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
- char * password) = 0;
- /** Change the active state of a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param enabled enable (true) or disable (false) the lockingrange
- * @param password Password of administrative authority for locking range
- */
- virtual uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
- char * password) = 0;
- /** Setup a locking range. Initialize a locking range, set it's start
- * LBA and length, initialize it as unlocked with locking disabled.
- * @paran lockingrange The Locking Range to be setup
- * @param start Starting LBA
- * @param length Number of blocks
- * @param password Password of administrator
- */
- virtual uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password) = 0;
- /** Setup a locking range in Single User Mode. Initialize a locking range,
- * set it's start LBA and length, initialize it as unlocked with locking enabled.
- * @paran lockingrange The Locking Range to be setup
- * @param start Starting LBA
- * @param length Number of blocks
- * @param password Password of administrator
- */
- virtual uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password) = 0;
- /** List status of locking ranges.
- * @param password Password of administrator
- */
- virtual uint8_t listLockingRanges(char * password, int16_t rangeid) = 0;
- /** Generate a new encryption key for a locking range.
- * @param lockingrange locking range number
- * @param password password of the locking administrative authority
- */
- virtual uint8_t rekeyLockingRange(uint8_t lockingrange, char * password) = 0;
- /** Enable bands using MSID.
- * @param lockingrange locking range number
- */
- virtual uint8_t setBandsEnabled(int16_t rangeid, char * password) = 0;
- /** Primitive to set the MBRDone flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- virtual uint8_t setMBRDone(uint8_t state, char * Admin1Password) = 0;
- /** Primitive to set the MBREnable flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- virtual uint8_t setMBREnable(uint8_t state, char * Admin1Password) = 0;
- /** enable a locking sp user.
- * @param password password of locking sp administrative authority
- * @param userid the user to be enabled
- */
- virtual uint8_t enableUser(char * password, char * userid, OPAL_TOKEN status = OPAL_TOKEN::OPAL_TRUE) = 0;
- /** Enable locking on the device
- * @param password password of the admin sp SID authority
- */
- virtual uint8_t activateLockingSP(char * password) = 0;
- /** Enable locking on the device in Single User Mode
- * @param lockingrange the locking range number to activate in SUM
- * @param password password of the admin sp SID authority
- */
- virtual uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password) = 0;
- /** Erase a Single User Mode locking range by calling the drive's erase method
- * @param lockingrange The Locking Range to erase
- * @param password The administrator password for the drive
- */
- 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
- */
- virtual uint8_t takeOwnership(char * newpassword) = 0;
- /** Reset the Locking SP to its factory default condition
- * ERASES ALL DATA!
- * @param password of Administrative user
- * @param keep true false for noerase function NOT WWORKING
- */
- virtual uint8_t revertLockingSP(char * password, uint8_t keep = 0) = 0;
- /** Reset the TPER to its factory condition
- * ERASES ALL DATA!
- * @param password password of authority (SID or PSID)
- * @param PSID true or false is the authority the PSID
- * */
- virtual uint8_t revertTPer(char * password, uint8_t PSID = 0, uint8_t AdminSP = 0 ) = 0;
- /** Erase a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param password Password of administrative authority for locking range
- */
- virtual uint8_t eraseLockingRange(uint8_t lockingrange, char * password) = 0;
- /** Dumps an object for diagnostic purposes
- * @param sp index into the OPALUID table for the SP the object is in
- * @param auth the authority ti use for the dump
- * @param pass the password for the suthority
- * @param objID the UID of the object to dump
- * */
- virtual uint8_t objDump(char *sp, char * auth, char *pass,
- char * objID) = 0;
- /** Issue any command to the drive for diagnostic purposes
- * @param sp index into the OPALUID table for the SP the object is in
- * @param auth the authority ti use for the dump
- * @param pass the password for the suthority
- * @param invoker caller of the method
- * @param method the method to call
- * @param plist the parameter list for the command
- *
- */
- virtual uint8_t rawCmd(char *sp, char * auth, char *pass,
- char *invoker, char *method, char *plist) = 0;
- /** Read MSID
- */
- virtual uint8_t printDefaultPassword() = 0;
- /*
- * virtual functions required to be implemented
- * because they are called by DtaSession.cpp
- */
- /** Send a command to the device and wait for the response
- * @param cmd the MswdCommand object containing the command
- * @param response the DtaResonse object containing the response
- * @param protocol The security protocol number to use for the command
- */
- virtual uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 0x01) = 0;
- /** 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 */
- sedutiloutput output_format; /** standard, readable, JSON */
+ /** Default constructor, does nothing */
+ DtaDev();
+ /** Default destructor, does nothing*/
+ virtual ~DtaDev();
+
+ /** Factory method to produce instance of appropriate subclass
+ * @param devref name of the device in the OS lexicon
+ * @param device reference into which to store the address of the new instance
+ * @param genericIfNotTPer if true, store an instance of DtaDevGeneric for non-TPers;
+ * if false, store NULL for non-TPers
+ */
+ static uint8_t getDtaDev(const char * devref, DtaDev * & device,
+ bool genericIfNotTPer=false);
+
+ /** Does the device conform to FIPS reqs */
+ uint8_t isFIPS();
+ /** Does the device conform to the RUBY SSC */
+ uint8_t isRuby();
+ /** Does the device conform to the OPALITE SSC */
+ uint8_t isOpalite();
+ /** Does the device conform to the PYRITE SSC */
+ uint8_t isPyrite();
+ uint8_t isPyrite2();
+ uint8_t isOpal2_minor_v(); /* OPAL 2 subversion */
+ uint8_t isOpal2_version(); /* descriptor version */
+ /** Does the device conform to the OPAL 2.0 SSC */
+ uint8_t isOpal2();
+ /** Does the device conform to the OPAL 1.0 SSC */
+ uint8_t isOpal1();
+ /** Does the device conform to the OPAL Enterprise SSC */
+ uint8_t isEprise();
+ /** Does the device conform to ANY TCG storage SSC */
+ uint8_t isAnySSC();
+ /** Is the MBREnabled flag set */
+ uint8_t MBREnabled();
+ /** Is the MBRDone flag set */
+ uint8_t MBRDone();
+ /** Is the Locked flag set */
+ uint8_t Locked();
+ /** Is the Locking SP enabled */
+ uint8_t LockingEnabled();
+ /** Is there an OS disk represented by this object */
+ uint8_t isPresent();
+ /** Is device on NVME bus */
+ uint8_t isNVMEbus();
+ /** Returns the Firmware revision reported by the identify command */
+ char *getFirmwareRev();
+ /** Returns the Model Number reported by the Identify command */
+ char *getModelNum();
+ /** Returns the Serial Number reported by the Identify command */
+ char *getSerialNum();
+ /** Returns the device-specific data to be used as a password salt */
+ vectorgetPasswordSalt();
+ /** Returns the Vendor ID reported by the Identify command */
+ char *getVendorID();
+ /** Returns the Manufacturer Name reported by the Identify command */
+ char *getManufacturerName();
+ /** Returns the World Wide Name reported by the Identify command */
+ vectorgetWorldWideName();
+ /** Returns whether the World Wide Name was synthesized from the Manufacturer Name and Serial Number */
+ bool isWorldWideNameSynthetic();
+
+
+ /* What type of disk attachment is used */
+ DTA_DEVICE_TYPE getDevType();
+ /** displays the information returned by the Discovery 0 reply */
+ virtual void puke();
+ //
+ int TperReset();
+ /*
+ * virtual methods required in the OS specific
+ * device class
+ */
+ /** OS specific method to send an ATA command to the device
+ * @param cmd ATA command to be sent to the device
+ * @param protocol security protocol to be used in the command
+ * @param comID communications ID to be used
+ * @param buffer input/output buffer
+ * @param bufferlen length of the input/output buffer
+ */
+ virtual uint8_t sendCmd(ATACOMMAND cmd, uint8_t protocol, uint16_t comID,
+ void * buffer, unsigned int bufferlen) = 0;
+ /** OS specific command to Wait for specified number of milliseconds
+ * @param milliseconds number of milliseconds to wait
+ */
+ virtual void osmsSleep(uint32_t milliseconds) = 0;
+ /** OS specific routine to identify the device and fill out the device information struct*/
+ virtual bool identify(DTA_DEVICE_INFO& disk_info) = 0;
+ /** OS specific routine to get size of the device */
+ virtual const unsigned long long getSize() = 0;
+ /*
+ * virtual functions required to be implemented
+ * because they are called by sedutil.cpp
+ */
+ /** 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
+ */
+ virtual uint8_t initialSetup(char * password) = 0;
+ /** 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
+ */
+ virtual uint8_t multiUserSetup(char *) __unimplemented__;
+ /** 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
+ */
+ virtual uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password) = 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
+ */
+ virtual uint8_t setSIDPassword(char * oldpassword, char * newpassword,
+ uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) = 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
+ */
+ virtual uint8_t setPassword(char * password, char * userid, char * newpassword, uint8_t idx=0) = 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 activate(char * password) = 0;
+ virtual uint8_t getmfgstate(void) = 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
+ */
+ virtual uint8_t loadPBA(char * password, char * filename) = 0;
+ /** Change the locking state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param lockingstate the locking state to set
+ * @param Admin1Password password of administrative authority for locking range
+ */
+ virtual uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate, char * Admin1Password, uint8_t idx=0) = 0;
+ /** Change the locking state of a locking range in Single User Mode
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param lockingstate the locking state to set
+ * @param password password of user authority for the locking range
+ */
+ virtual uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
+ char * password) = 0;
+ /** Change the active state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param enabled enable (true) or disable (false) the lockingrange
+ * @param password Password of administrative authority for locking range
+ */
+ virtual uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
+ char * password, uint8_t idx=0) = 0;
+ /** Setup a locking range. Initialize a locking range, set it's start
+ * LBA and length, initialize it as unlocked with locking disabled.
+ * @paran lockingrange The Locking Range to be setup
+ * @param start Starting LBA
+ * @param length Number of blocks
+ * @param password Password of administrator
+ */
+ virtual uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password) = 0;
+ /** Setup a locking range in Single User Mode. Initialize a locking range,
+ * set it's start LBA and length, initialize it as unlocked with locking enabled.
+ * @paran lockingrange The Locking Range to be setup
+ * @param start Starting LBA
+ * @param length Number of blocks
+ * @param password Password of administrator
+ */
+ virtual uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password) = 0;
+ /** List status of locking ranges.
+ * @param password Password of administrator
+ */
+ virtual uint8_t listLockingRanges(char * password, int16_t rangeid, uint8_t idx=0) = 0;
+ /** Generate a new encryption key for a locking range.
+ * @param lockingrange locking range number
+ * @param password password of the locking sp administrative authority
+ */
+ virtual uint8_t rekeyLockingRange(uint8_t lockingrange, char * password) = 0;
+ /** Enable bands using MSID.
+ * @param rangeid locking range number
+ */
+ virtual uint8_t setBandsEnabled(int16_t rangeid, char * password) = 0;
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1Password password of the locking sp administrative authority
+ */
+ virtual uint8_t setMBRDone(uint8_t state, char * Admin1Password) = 0;
+
+
+ virtual uint8_t TCGreset(uint8_t state) = 0;
+
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1Password password of the locking sp administrative authority
+ */
+ virtual uint8_t setMBREnable(uint8_t state, char * Admin1Password) = 0;
+
+ /** enable a locking sp user.
+ * @param state 0 or 1
+ * @param password password of locking sp administrative authority
+ * @param userid the user to be enabled
+ */
+ virtual uint8_t enableUser(uint8_t state, char * password, char * userid) = 0;
+ /** Enable locking on the device
+ * @param state 0 or 1
+ * @param password password of the admin sp SID authority
+ */
+ virtual uint8_t enableUserRead(uint8_t state, char * password, char * userid) = 0;
+
+ /** Enable locking on the device
+ * @param password password of the admin sp SID authority
+ */
+ virtual uint8_t activateLockingSP(char * password) = 0;
+
+ /** Enable locking on the device
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ virtual uint8_t activateLockingSP(vectorHostChallenge) = 0;
+
+ /** Enable locking on the device in Single User Mode
+ * @param lockingrange the locking range number to activate in SUM
+ * @param password password of the admin sp SID authority
+ */
+ virtual uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password) = 0;
+ /** Erase a Single User Mode locking range by calling the drive's erase method
+ * @param lockingrange The Locking Range to erase
+ * @param password The administrator password for the drive
+ */
+ 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
+ */
+ virtual uint8_t takeOwnership(char * newpassword) = 0;
+
+ /** Reset the Locking SP to its factory default condition
+ * ERASES ALL DATA!
+ * @param password of Administrative user
+ * @param keep true false for noerase function NOT WWORKING
+ */
+ virtual uint8_t revertLockingSP(char * password, uint8_t keep = 0) = 0;
+
+ /** Reset the TPER to its factory condition
+ * @param password password of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * @param AdminSP true or false is the SP the AdminSP or ThisSP (Enterprise Only)
+ */
+ virtual uint8_t revertTPer(char * password, uint8_t PSID = 0, uint8_t AdminSP = 0 ) = 0;
+
+ /** Erase a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param password Password of administrative authority for locking range
+ */
+ virtual uint8_t eraseLockingRange(uint8_t lockingrange, char * password) = 0;
+ /** Dumps an object for diagnostic purposes
+ * @param sp index into the OPALUID table for the SP the object is in
+ * @param auth the authority ti use for the dump
+ * @param pass the password for the suthority
+ * @param objID the UID of the object to dump
+ */
+ virtual uint8_t objDump(char *sp, char * auth, char *pass,
+ char * objID) = 0;
+ /** Issue any command to the drive for diagnostic purposes
+ * @param sp index into the OPALUID table for the SP the object is in
+ * @param auth the authority ti use for the dump
+ * @param pass the password for the suthority
+ * @param invoker caller of the method
+ * @param method the method to call
+ * @param plist the parameter list for the command
+ */
+ virtual uint8_t rawCmd(char *sp, char * auth, char *pass,
+ char *invoker, char *method, char *plist) = 0;
+
+
+ /** Primitive to extract the MSID into a std::string
+ * @param MSID the string to receive the MSID
+ */
+ virtual uint8_t getMSID(string& MSID) = 0;
+
+ /** Primitive to print the MSID to stdout
+ */
+ virtual uint8_t printDefaultPassword() = 0;
+
+ /// The methods below are slightly lower-level versions of the similarly-named ones above.
+ /// They differ in that they take a byte vector host challenge that is passed through
+ /// unchanged, i.e. not a null-terminated C string, and not (possibly) hashed.
+
+ /** 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
+ * @param lockingstate desired locking state (see above)
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ virtual uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
+ vector Admin1HostChallenge, uint8_t idx=0)=0;
+
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ virtual uint8_t setMBRDone(uint8_t state, vector Admin1HostChallenge) = 0;
+
+
+ /** User command to prepare the device for management by sedutil.
+ * Specific to the SSC that the device supports
+ * @param HostChallenge the HostChallenge that is to be assigned to the SSC master entities
+ */
+ virtual uint8_t initialSetup(vector HostChallenge) = 0;
+
+ /** User command to prepare the device for management by sedutil.
+ * Specific to the SSC that the device supports
+ * @@param hostChallenge the password that is to be assigned to the SSC master entities
+ */
+ virtual uint8_t multiUserSetup(vector) __unimplemented__;
+
+ /** Change the SID HostChallenge from its MSID default
+ * @param HostChallenge new HostChallenge for SID and locking SP admins
+ */
+ virtual uint8_t takeOwnership(vector HostChallenge) = 0;
+ /** Change the active state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param enabled enable (true) or disable (false) the lockingrange
+ * @param HostChallenge HostChallenge of administrative authority for locking range
+ */
+ virtual uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
+ vector HostChallenge, uint8_t idx=0) = 0;
+
+ /** Set the SID password.
+ * @param oldHostChallenge current SID host challenge
+ * @param newHostChallenge value host challenge is to be changed to
+ * @note neither value is hashed
+ */
+ virtual uint8_t setSIDHostChallenge(vector oldHostChallenge,
+ vector newHostChallenge) = 0;
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ virtual uint8_t setMBREnable(uint8_t state, vector Admin1HostChallenge) = 0;
+
+ /** Set the host challenge of a locking SP user.
+ * Note that the version above of this method is called setPassword
+ * @param currentHostChallenge current host challenge
+ * @param userid the userid whose host challenge is to be changed
+ * @param newHostChallenge value host challenge is to be changed to
+ */
+ virtual uint8_t setHostChallenge(vector currentHostChallenge, char * userid,
+ vector newHostChallenge, uint8_t idx=0) = 0;
+
+
+ /** enable a locking sp user.
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of locking sp administrative authority
+ * @param userid the user to be enabled
+ */
+ virtual uint8_t enableUser(uint8_t state, vector HostChallenge, char * userid) = 0;
+
+ /** Enable locking on the device
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ virtual uint8_t enableUserRead(uint8_t state, vector HostChallenge, char * userid) = 0;
+
+ /** Reset the Locking SP to its factory default condition
+ * ERASES ALL DATA!
+ * @param HostChallenge of Administrative user
+ * @param keep true false for noerase function NOT WWORKING
+ */
+ virtual uint8_t revertLockingSP(vector HostChallenge, uint8_t keep = 0) = 0;
+
+ /** Reset the TPER to its factory condition
+ * @param HostChallenge HostChallenge of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * @param AdminSP true or false is the SP the AdminSP or ThisSP (Enterprise Only)
+ */
+ virtual uint8_t revertTPer(vector HostChallenge, uint8_t PSID = 0, uint8_t AdminSP = 0 ) = 0;
+
+
+
+ /// Wrapper methods that allow concise TPer function methods
+
+ /** Start a session using some kind of authentication, and
+ * then do something within that session.
+ * This method handles errors starting the session, and cleans
+ * up by deleting the session afterwards,
+ * returning the result of any session start error
+ * or otherwise the result of the session body function
+ *
+ * Note that it is expected that these "function" parameters
+ * will probably be closures.
+ *
+ * @param startSessionFn a function that starts a session, returning a uint8_t
+ * @param sessionBodyFn a function that runs within that session, returning a uint8_t
+ */
+ uint8_t WithSession(std::functionstartSessionFn,
+ std::functionsessionBodyFn);
+
+ /** Start a session using a simple start method call, and
+ * then do something within that session.
+ * This method handles errors starting the session, and cleans
+ * up by deleting the session afterwards,
+ * returning the result of any session start error
+ * or otherwise the result of the session body function
+ *
+ * Note that it is expected that these "function" parameters
+ * will probably be closures.
+ *
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * @param sessionBodyFn a function that runs within that session, returning a uint8_t
+ */
+ template
+ uint8_t WithSimpleSession(OPAL_UID SP, PasswordType password, AuthorityType SignAuthority,
+ std::functionsessionBodyFn) {
+ std::functionstartSessionFn = [this, SP, password, SignAuthority](){
+ return start(SP, password, SignAuthority);
+ };
+ return WithSession(startSessionFn, sessionBodyFn);
+ }
+
+
+ /** Start a session using some kind of authentication,
+ * create a DtaCommand object, and then runs that command within that session.
+ * This method handles errors starting the session and creating the command,
+ * and cleans up by deleting the command and session afterwards,
+ * returning the result of any session start error
+ * or command creation error
+ * or otherwise the result of executing sendCommand on the command
+ * leaving the response in the response instance variable
+ *
+ * Note that it is expected that these "function" parameters
+ * will probably be closures.
+ *
+ * @param startSessionFn a function that starts a session, returning a uint8_t
+ * @param commandWriterFn a function that runs within that session,
+ * takes a DtaCommand parameter,
+ * and writes into that DtaCommand
+ * and then simply returns no value
+ */
+
+
+ uint8_t WithSessionCommand(std::functionstartSessionFn,
+ std::functioncommandWriterFn);
+
+
+ /** Start a session using a simple start method call, and
+ * create a DtaCommand object, and then runs that command within that session.
+ * This method handles errors starting the session and creating the command,
+ * and cleans up by deleting the command and session afterwards,
+ * returning the result of any session start error
+ * or command creation error
+ * or otherwise the result of executing sendCommand on the command
+ * leaving the response in the response instance variable
+ *
+ * Note that it is expected that these "function" parameters
+ * will probably be closures.
+ *
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * @param commandWriterFn a function that runs within that session,
+ * takes a DtaCommand parameter,
+ * and writes into that DtaCommand
+ * and then simply returns no value
+ */
+ template
+ uint8_t WithSimpleSessionCommand(OPAL_UID SP, PasswordType password, AuthorityType SignAuthority,
+ std::functioncommandWriterFn) {
+ std::functionstartSessionFn = [this, SP, password, SignAuthority](){
+ return start(SP, password, SignAuthority);
+ };
+ return WithSessionCommand(startSessionFn, commandWriterFn);
+ }
+
+
+ /**
+ * virtual functions required to be implemented
+ * because they are called by DtaSession.cpp
+ */
+
+ /** Send a command to the device and wait for the response
+ * @param cmd the MswdCommand object containing the command
+ * @param response the DtaResonse object containing the response
+ * @param protocol The security protocol number to use for the command
+ */
+ virtual uint8_t exec(DtaCommand * cmd, DtaResponse & response, uint8_t protocol = 0x01) = 0;
+ /** return the communications ID to be used for sessions to this device */
+ virtual uint16_t comID() = 0;
+
+ bool no_hash_passwords = FALSE; /** disables hashing of passwords */
+ bool usermodeON = FALSE;
+ bool translate_req = FALSE;
+ bool skip_activate = FALSE;
+ sedutiloutput output_format; /** standard, readable, JSON */ // TODO: really an attribute of the program, not the TPer
+
+ char LicenseLevel[32]; // TODO: see comment at the top???
+
+
protected:
- const char * dev; /**< character string representing the device in the OS lexicon */
- uint8_t isOpen = FALSE; /**< The device has been opened */
- OPAL_DiskInfo disk_info; /**< Structure containing info from identify and discovery 0 */
- DtaResponse response; /**< shared response object */
- DtaResponse propertiesResponse; /**< response fron properties exchange */
- DtaSession *session; /**< shared session object pointer */
- uint8_t discovery0buffer[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT];
- uint32_t tperMaxPacket = 2048;
- uint32_t tperMaxToken = 1950;
+ const char * dev; /**< character string representing the device in the OS lexicon */
+ DTA_DEVICE_INFO disk_info; /**< Structure containing info from identify and discovery 0 */
+
+ uint8_t isOpen = FALSE; /**< The device has been opened */
+ uint8_t isNVME = FALSE; /**< This device is NVME */
+
+ uint8_t adj_host = FALSE;
+ uint16_t adj_io_buffer_length = 2048; // 10240; // 17408; // user safe low buffer length
+
+ DtaResponse response; /**< shared response object */
+ DtaResponse propertiesResponse; /**< response from properties exchange */
+ DtaSession *session; /**< shared session object pointer */
+
+ /** start an anonymous session
+ * @param SP the Security Provider to start the session with */
+ uint8_t start(OPAL_UID SP);
+
+
+ /** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ */
+ uint8_t start(OPAL_UID SP, char * password, OPAL_UID SignAuthority);
+
+
+
+ /** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param HostChallenge the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ */
+ uint8_t start(OPAL_UID SP, vector HostChallenge, OPAL_UID SignAuthority);
+
+
+ /** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param password the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * */
+ uint8_t start(OPAL_UID SP, char * password, vector SignAuthority);
+
+
+ /** Start an authenticated session (OPAL only)
+ * @param SP the securitly provider to start the session with
+ * @param HostChallenge the password to start the session
+ * @param SignAuthority the Signing authority (in a simple session this is the user)
+ * */
+ uint8_t start(OPAL_UID SP, vector HostChallenge, vector SignAuthority);
+
+
+
+ uint8_t discovery0buffer[MIN_BUFFER_LENGTH + IO_BUFFER_ALIGNMENT] ; // NG->__attribute__((aligned(16)));
+
+ uint32_t Tper_sz_MaxComPacketSize = 2048;
+ uint32_t Tper_sz_MaxResponseComPacketSize = 2048;
+ uint32_t Tper_sz_MaxPacketSize = 2028;
+ uint32_t Tper_sz_MaxIndTokenSize = 1992;
+ uint32_t Host_sz_MaxComPacketSize = 2048;
+ uint32_t Host_sz_MaxResponseComPacketSize = 2048;
+ uint32_t Host_sz_MaxPacketSize = 2028 ;
+ uint32_t Host_sz_MaxIndTokenSize = 1992 ;
};
+
+
+static inline bool __is_all_NULs(const uint8_t * b, const unsigned int n) {
+ for (const uint8_t * e = b + n; b & v, const uint8_t value[8])
+{
+ v.clear();
+ v.push_back(OPAL_SHORT_ATOM::BYTESTRING8);
+ for (int i = 0; i < 8; i++)
+ {
+ v.push_back(value[i]);
+ }
+}
+
+
+
+static inline vector vUID(OPAL_UID uid)
+{
+ vector v(9);
+ set8(v,OPALUID[uid]);
+ return v;
+}
diff --git a/Common/DtaDevEnterprise.cpp b/Common/DtaDevEnterprise.cpp
index 76e6e39d..2e383eda 100644
--- a/Common/DtaDevEnterprise.cpp
+++ b/Common/DtaDevEnterprise.cpp
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This software is Copyright 2017 Spectra Logic Corporation
This file is part of sedutil.
@@ -18,11 +18,14 @@ 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
#include
-#include
+#include
#include "DtaDevEnterprise.h"
#include "DtaHashPwd.h"
#include "DtaEndianFixup.h"
@@ -57,18 +60,6 @@ static const bool is_NULL_UID(std::vector & v)
;
}
-////////////////////////////////////////////////////////////////////////////////
-static void set8(vector & v, const uint8_t value[8])
-////////////////////////////////////////////////////////////////////////////////
-{
- v.clear();
- v.push_back(OPAL_SHORT_ATOM::BYTESTRING8);
- for (int i = 0; i < 8; i++)
- {
- v.push_back(value[i]);
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
static void setband(vector & v, uint16_t i)
////////////////////////////////////////////////////////////////////////////////
@@ -79,7 +70,7 @@ static void setband(vector & v, uint16_t i)
}
////////////////////////////////////////////////////////////////////////////////
-static void user2cpin(vector & dst, vector & src)
+static void user2cpin(vector & dst, const vector & src)
////////////////////////////////////////////////////////////////////////////////
{
// this works for BandMasterN and EraseMaster
@@ -89,47 +80,48 @@ static void user2cpin(vector & dst, vector & src)
}
////////////////////////////////////////////////////////////////////////////////
-uint8_t DtaDevEnterprise::getMaxRanges(char * password, uint16_t *maxRanges)
+uint8_t DtaDevEnterprise::getMaxRanges(uint16_t *maxRanges)
////////////////////////////////////////////////////////////////////////////////
{
- uint8_t lastRC;
-
- // 5.7.2.1.5 MaxRanges
- // This value defines the maximum number of supportable LBA ranges in addition
- // to the Global Range. If this value is 0, then the only range available is
- // the entire Global Range of the Storage Device.
- //
- // Therefore: 0 <= supported range <= MaxRanges
-
- // create session
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID)) != 0) {
- delete session;
- return lastRC;
- }
-
- //** Table 36 "LockingInfo table", p. 72 of Enterprise SSC rev 3.00
- vector table;
- set8(table, OPALUID[ENTERPRISE_LOCKING_INFO_TABLE]);
-
- // query row 1 of LockingInfo table
- if ((lastRC = getTable(table, "MaxRanges", "MaxRanges")) != 0) {
- delete session;
- return getMaxRangesOpal(password, maxRanges);
- }
- delete session;
-
- // "MaxRanges" is token 5 of response
- *maxRanges = response.getUint16(5);
- return 0;
+ uint8_t lastRC;
+
+ // 5.7.2.1.5 MaxRanges
+ // This value defines the maximum number of supportable LBA ranges in addition
+ // to the Global Range. If this value is 0, then the only range available is
+ // the entire Global Range of the Storage Device.
+ //
+ // Therefore: 0 <= supported range <= MaxRanges
+
+ // create session
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID)) != 0) {
+ delete session;
+ return lastRC;
+ }
+
+ //** Table 36 "LockingInfo table", p. 72 of Enterprise SSC rev 3.00
+ vector table;
+ set8(table, OPALUID[ENTERPRISE_LOCKING_INFO_TABLE]);
+
+ // query row 1 of LockingInfo table
+ if (getTable(table, "MaxRanges", "MaxRanges") != 0) {
+ delete session;
+ // Unable to get values from Enterprise LockingInfo table -- bail out to Opal
+ return getMaxRangesOpal(maxRanges);
+ }
+ delete session;
+
+ // "MaxRanges" is token 5 of response
+ *maxRanges = response.getUint16(5);
+ return 0;
}
////////////////////////////////////////////////////////////////////////////////
-uint8_t DtaDevEnterprise::getMaxRangesOpal(char * password, uint16_t *maxRanges)
+uint8_t DtaDevEnterprise::getMaxRangesOpal(uint16_t *maxRanges)
////////////////////////////////////////////////////////////////////////////////
{
uint8_t lastRC;
@@ -162,47 +154,70 @@ uint8_t DtaDevEnterprise::getMaxRangesOpal(char * password, uint16_t *maxRanges)
return 0;
}
-DtaDevEnterprise::DtaDevEnterprise(const char * devref)
-{
- DtaDevOS::init(devref);
- assert(isEprise());
- if (properties()) { LOG(E) << "Properties exchange failed"; }
-}
-DtaDevEnterprise::~DtaDevEnterprise()
-{
-}
+
uint8_t DtaDevEnterprise::initialSetup(char * password)
{
- LOG(D1) << "Entering initialSetup()";
- uint8_t lastRC;
+ LOG(D1) << "Entering initialSetup()";
+ uint8_t lastRC;
- if ((lastRC = takeOwnership(password)) != 0) {
- LOG(E) << "Initial setup failed - unable to take ownership";
- return lastRC;
- }
- if ((lastRC = setLockingRange(0,
+ if ((lastRC = takeOwnership(password)) != 0) {
+ LOG(E) << "Initial setup failed - unable to take ownership";
+ return lastRC;
+ }
+ if ((lastRC = setLockingRange(0,
OPAL_LOCKINGSTATE::READWRITE, password)) != 0) {
- LOG(E) << "Initial setup failed - unable to unlock for read/write";
- return lastRC;
- }
-
- if ((lastRC = configureLockingRange(0,
- (DTA_READLOCKINGENABLED | DTA_WRITELOCKINGENABLED), password)) != 0) {
- LOG(E) << "Initial setup failed - unable to enable read/write locking";
- return lastRC;
- }
-
- LOG(I) << "Initial setup of TPer complete on " << dev;
- LOG(D1) << "Exiting initialSetup()";
- return 0;
+ LOG(E) << "Initial setup failed - unable to unlock for read/write";
+ return lastRC;
+ }
+
+ if ((lastRC = configureLockingRange(0,
+ (DTA_READLOCKINGENABLED | DTA_WRITELOCKINGENABLED), password)) != 0) {
+ LOG(E) << "Initial setup failed - unable to enable read/write locking";
+ return lastRC;
+ }
+
+ LOG(D) << "Initial setup of TPer complete on " << dev;
+ LOG(D1) << "Exiting initialSetup()";
+ return 0;
+}
+
+
+uint8_t DtaDevEnterprise::initialSetup(vector HostChallenge)
+{
+ LOG(D1) << "Entering initialSetup()";
+ uint8_t lastRC;
+
+ if ((lastRC = takeOwnership(HostChallenge)) != 0) {
+ LOG(E) << "Initial setup failed - unable to take ownership";
+ return lastRC;
+ }
+ if ((lastRC = setLockingRange(0,
+ OPAL_LOCKINGSTATE::READWRITE, HostChallenge)) != 0) {
+ LOG(E) << "Initial setup failed - unable to unlock for read/write";
+ return lastRC;
+ }
+
+ if ((lastRC = configureLockingRange(0,
+ (DTA_READLOCKINGENABLED | DTA_WRITELOCKINGENABLED), HostChallenge)) != 0) {
+ LOG(E) << "Initial setup failed - unable to enable read/write locking";
+ return lastRC;
+ }
+
+ LOG(D) << "Initial setup of TPer complete on " << dev;
+ LOG(D1) << "Exiting initialSetup()";
+ return 0;
}
+
+
uint8_t DtaDevEnterprise::setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password)
{
LOG(D1) << "Entering DtaDevEnterprise::setup_SUM";
- LOG(I) << "setup_SUM not supported on DtaDevEnterprise";
+ LOG(D) << "setup_SUM not supported on DtaDevEnterprise";
return 1;
}
-uint8_t DtaDevEnterprise::configureLockingRange(uint8_t lockingrange, uint8_t enabled, char * password)
+
+
+uint8_t DtaDevEnterprise::configureLockingRange(uint8_t lockingrange, uint8_t enabled, char * password, uint8_t)
{
uint8_t lastRC;
LOG(D1) << "Entering DtaDevEnterprise::configureLockingRange()";
@@ -227,7 +242,7 @@ uint8_t DtaDevEnterprise::configureLockingRange(uint8_t lockingrange, uint8_t en
return lastRC;
}
- /* can't use settable because the segate drives require that both the
+ /* can't use settable because the segate drives require that both the
* read & write lockenabled be changed at the same time. I can find no
* written doc on such a restriction but .....
*/
@@ -273,10 +288,67 @@ uint8_t DtaDevEnterprise::configureLockingRange(uint8_t lockingrange, uint8_t en
}
delete set;
delete session;
- LOG(I) << "Locking range configured " << (uint16_t) enabled;
+ LOG(D) << "Locking range configured " << (uint16_t) enabled;
LOG(D1) << "Exiting DtaDevEnterprise::configureLockingRange()";
return 0;
}
+
+
+
+uint8_t DtaDevEnterprise::configureLockingRange(uint8_t lockingrange, uint8_t enabled, vector HostChallenge, uint8_t)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::configureLockingRange()";
+
+ //** BandMaster0 UID of Table 28 Locking SP Authority table, p. 70 of Enterprise SSC rev 3.00
+ vector user=vUID(OPAL_UID::ENTERPRISE_BANDMASTER0_UID);
+ setband(user, lockingrange);
+
+ //** Global_Range UID of Table 33 Locking SP Locking table, p. 84 of Enterprise SSC rev 3.00
+ vector object=vUID(OPAL_UID::OPAL_LOCKINGRANGE_GLOBAL);
+ setband(object, lockingrange);
+
+ uint8_t lastRC= WithSimpleSessionCommand(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, HostChallenge, user,
+ [object, enabled](DtaCommand * set){
+ vector method;
+ set8(method, OPALMETHOD[OPAL_METHOD::ESET]);
+ set->reset(object, method);
+
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTNAME);
+ set->addToken("ReadLockEnabled");
+ set->addToken((enabled & DTA_READLOCKINGENABLED) ? OPAL_TRUE : OPAL_FALSE);
+ set->addToken(OPAL_TOKEN::ENDNAME);
+ set->addToken(OPAL_TOKEN::STARTNAME);
+ set->addToken("WriteLockEnabled");
+ set->addToken((enabled & DTA_WRITELOCKINGENABLED) ? OPAL_TRUE : OPAL_FALSE);
+ set->addToken(OPAL_TOKEN::ENDNAME);
+ set->addToken(OPAL_TOKEN::STARTNAME);
+ set->addToken("LockOnReset");
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(UINT_00);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::ENDNAME);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+
+ set->complete();
+ });
+
+ if (lastRC != 0) {
+ LOG(E) << "Set Failed ";
+ } else {
+ LOG(D) << "Locking range configured " << (uint16_t) enabled;
+ LOG(D1) << "Exiting DtaDevEnterprise::configureLockingRange()";
+ }
+ return lastRC;
+}
+
+
uint8_t DtaDevEnterprise::rekeyLockingRange(uint8_t lockingrange, char * password)
{
LOG(D1) << "Entering DtaDevEnterprise::rekeyLockingRange()";
@@ -308,7 +380,7 @@ uint8_t DtaDevEnterprise::rekeyLockingRange(uint8_t lockingrange, char * passwor
std::vector ActiveKey = response.getRawToken(5);
if (is_NULL_UID(ActiveKey))
{
- LOG(I) << "LockingRange" << (uint16_t)lockingrange << " remains in plaintext ";
+ LOG(D) << "LockingRange" << (uint16_t)lockingrange << " remains in plaintext ";
delete session;
return 0;
}
@@ -331,159 +403,276 @@ uint8_t DtaDevEnterprise::rekeyLockingRange(uint8_t lockingrange, char * passwor
}
delete rekey;
delete session;
- LOG(I) << "LockingRange" << (uint16_t)lockingrange << " reKeyed ";
+ LOG(D) << "LockingRange" << (uint16_t)lockingrange << " reKeyed ";
LOG(D1) << "Exiting DtaDevEnterprise::rekeyLockingRange()";
return 0;
}
uint8_t DtaDevEnterprise::revertLockingSP(char * password, uint8_t keep)
{
- LOG(D1) << "Entering DtaDevEnterprise::revertLockingSP()";
- if(password == NULL) { LOG(D4) << "Referencing formal parameters " << keep; }
- uint8_t lastRC;
- DtaCommand *cmd = new DtaCommand();
- if (NULL == cmd) {
- LOG(E) << "Unable to create command object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session = new DtaSession(this);
- if (NULL == session) {
- LOG(E) << "Unable to create session object ";
- delete cmd;
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- OPAL_UID uid = OPAL_UID::OPAL_SID_UID;
- if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, password, uid)) != 0) {
- delete cmd;
- delete session;
- return lastRC;
- }
- cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
- cmd->addToken(OPAL_TOKEN::STARTLIST);
- cmd->addToken(OPAL_TOKEN::STARTNAME);
- cmd->addToken("KeepGlobalRangeKey");
- cmd->addToken(keep);
- cmd->addToken(OPAL_TOKEN::ENDNAME);
- cmd->addToken(OPAL_TOKEN::ENDLIST);
- cmd->complete();
- session->expectAbort();
- if ((lastRC = session->sendCommand(cmd, response)) != 0) {
- delete cmd;
- delete session;
- return lastRC;
- }
- LOG(I) << "revertLockingSP completed successfully";
- delete cmd;
- delete session;
- LOG(D1) << "Exiting DtaDevEnterprise::revertLockingSP()";
- return 0;
+ LOG(D1) << "Entering DtaDevEnterprise::revertLockingSP()";
+ if(password == NULL) { LOG(D4) << "Referencing formal parameters " << keep; }
+ uint8_t lastRC;
+ DtaCommand *cmd = new DtaCommand();
+ if (NULL == cmd) {
+ LOG(E) << "Unable to create command object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session = new DtaSession(this);
+ if (NULL == session) {
+ LOG(E) << "Unable to create session object ";
+ delete cmd;
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ OPAL_UID uid = OPAL_UID::OPAL_SID_UID;
+ if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, password, uid)) != 0) {
+ delete cmd;
+ delete session;
+ return lastRC;
+ }
+ cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
+ cmd->addToken(OPAL_TOKEN::STARTLIST);
+ cmd->addToken(OPAL_TOKEN::STARTNAME);
+ cmd->addToken("KeepGlobalRangeKey");
+ cmd->addToken(keep);
+ cmd->addToken(OPAL_TOKEN::ENDNAME);
+ cmd->addToken(OPAL_TOKEN::ENDLIST);
+ cmd->complete();
+ session->expectAbort();
+ if ((lastRC = session->sendCommand(cmd, response)) != 0) {
+ delete cmd;
+ delete session;
+ return lastRC;
+ }
+ LOG(D) << "revertLockingSP completed successfully";
+ delete cmd;
+ delete session;
+ LOG(D1) << "Exiting DtaDevEnterprise::revertLockingSP()";
+ return 0;
}
-uint8_t DtaDevEnterprise::setPassword(char * password, char * userid, char * newpassword)
+
+uint8_t DtaDevEnterprise::revertLockingSP(vector HostChallenge, uint8_t keep)
{
- LOG(D1) << "Entering DtaDevEnterprise::setPassword" ;
- uint8_t lastRC;
- string defaultPassword;
- char *pwd = password, *newpwd = newpassword;
+ LOG(D1) << "Entering DtaDevEnterprise::revertLockingSP()";
+ if(HostChallenge.size() == 0) { LOG(D4) << "Referencing formal parameters " << keep; }
+ uint8_t lastRC = WithSimpleSessionCommand(OPAL_UID::OPAL_ADMINSP_UID, HostChallenge, OPAL_UID::OPAL_SID_UID,
+ [this, keep](DtaCommand *cmd){
+ cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
+ cmd->addToken(OPAL_TOKEN::STARTLIST);
+ cmd->addToken(OPAL_TOKEN::STARTNAME);
+ cmd->addToken("KeepGlobalRangeKey");
+ cmd->addToken(keep);
+ cmd->addToken(OPAL_TOKEN::ENDNAME);
+ cmd->addToken(OPAL_TOKEN::ENDLIST);
+ cmd->complete();
+ session->expectAbort();
+ });
+ if (lastRC == 0) {
+ LOG(D) << "revertLockingSP completed successfully";
+ }
+ LOG(D1) << "Exiting DtaDevEnterprise::revertLockingSP()";
+ return 0;
+}
- if (11 > strnlen(userid, 15)) {
- LOG(E) << "Invalid Userid " << userid;
- return DTAERROR_INVALID_PARAMETER;
- }
+uint8_t DtaDevEnterprise::setPassword(char * password, char * userid, char * newpassword, uint8_t)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::setPassword" ;
+ uint8_t lastRC;
+ char *pwd = password, *newpwd = newpassword;
- std::vector user;
- if (!memcmp("BandMaster", userid, 10)) {
- uint16_t band = (uint16_t)atoi(&userid[10]);
- if (1023 < band) {
- LOG(E) << "Invalid Userid " << userid;
- return DTAERROR_INVALID_PARAMETER;
- }
- set8(user, OPALUID[OPAL_UID::ENTERPRISE_BANDMASTER0_UID]);
- setband(user, band);
- }
- else if (!memcmp("EraseMaster", userid, 11)) {
- set8(user, OPALUID[OPAL_UID::ENTERPRISE_ERASEMASTER_UID]);
- }
- else {
- LOG(E) << "Invalid Userid " << userid;
- return DTAERROR_INVALID_PARAMETER;
- }
+ if (11 > strnlen(userid, 15)) {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
- if ((password == NULL) || (*password == '\0') || (newpassword == NULL) ||
- (*newpassword == '\0')) {
- if ((lastRC = getDefaultPassword()) != 0) {
- LOG(E) << "setPassword failed to retrieve MSID";
- return lastRC;
- }
- defaultPassword = response.getString(5);
- if ((password == NULL) || (*password == '\0'))
- pwd = (char *)defaultPassword.c_str();
+ std::vector user;
+ if (!memcmp("BandMaster", userid, 10)) {
+ uint16_t band = (uint16_t)atoi(&userid[10]);
+ if (1023 < band) {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
+ set8(user, OPALUID[OPAL_UID::ENTERPRISE_BANDMASTER0_UID]);
+ setband(user, band);
+ }
+ else if (!memcmp("EraseMaster", userid, 11)) {
+ set8(user, OPALUID[OPAL_UID::ENTERPRISE_ERASEMASTER_UID]);
+ }
+ else {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
- if ((newpassword == NULL) || (*newpassword == '\0'))
- newpwd = (char *)defaultPassword.c_str();
- }
+ string defaultPassword;
+ if ((password == NULL) || (*password == '\0') || (newpassword == NULL) ||
+ (*newpassword == '\0')) {
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
+ LOG(E) << "setPassword failed to retrieve MSID";
+ return lastRC;
+ }
+ if ((password == NULL) || (*password == '\0'))
+ pwd = (char *)defaultPassword.c_str();
- std::vector usercpin;
- user2cpin(usercpin, user);
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- if ((password == NULL) || (*password == '\0'))
- session->dontHashPwd();
- if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, pwd, user)) != 0) {
- delete session;
- return lastRC;
- }
+ if ((newpassword == NULL) || (*newpassword == '\0'))
+ newpwd = (char *)defaultPassword.c_str();
+ }
- if ((newpassword == NULL) || (*newpassword == '\0')) {
- std::vector tmppwd;
+ std::vector usercpin;
+ user2cpin(usercpin, user);
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ if ((password == NULL) || (*password == '\0'))
+ session->dontHashPwd();
+ if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, pwd, user)) != 0) {
+ delete session;
+ return lastRC;
+ }
- tmppwd.push_back(0xd0);
- tmppwd.push_back((uint8_t)strnlen(newpwd, 255));
- for (unsigned int i = 0; i < strnlen(newpwd, 255); i++) {
- tmppwd.push_back(newpwd[i]);
- }
+ if ((newpassword == NULL) || (*newpassword == '\0')) {
+ std::vector tmppwd;
- if ((lastRC = setTable(usercpin, "PIN", tmppwd)) != 0) {
- LOG(E) << "Unable to set user " << userid << " new password ";
- delete session;
- return lastRC;
- }
- } else {
- std::vector hash;
- DtaHashPwd(hash, newpwd, this);
- if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
- LOG(E) << "Unable to set user " << userid << " new password ";
- delete session;
- return lastRC;
- }
- }
- LOG(I) << userid << " password changed";
- delete session;
- LOG(D1) << "Exiting DtaDevEnterprise::setPassword()";
- return 0;
+ tmppwd.push_back(0xd0);
+ tmppwd.push_back((uint8_t)strnlen(newpwd, 255));
+ for (unsigned int i = 0; i < strnlen(newpwd, 255); i++) {
+ tmppwd.push_back(newpwd[i]);
+ }
+
+ if ((lastRC = setTable(usercpin, "PIN", tmppwd)) != 0) {
+ LOG(E) << "Unable to set user " << userid << " new password ";
+ delete session;
+ return lastRC;
+ }
+ } else {
+ std::vector hash;
+ DtaHashPwd(hash, newpwd, this);
+ if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
+ LOG(E) << "Unable to set user " << userid << " new password ";
+ delete session;
+ return lastRC;
+ }
+ }
+
+ LOG(I) << userid << " password changed";
+ delete session;
+ LOG(D1) << "Exiting DtaDevEnterprise::setPassword()";
+ return 0;
+}
+
+
+
+uint8_t DtaDevEnterprise::setHostChallenge(vector currentHostChallenge, char * userid, vector newHostChallenge, uint8_t)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::setPassword" ;
+
+ if (11 > strnlen(userid, 15)) {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
+
+ std::vector user;
+ if (!memcmp("BandMaster", userid, 10)) {
+ uint16_t band = (uint16_t)atoi(&userid[10]);
+ if (1023 < band) {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
+ set8(user, OPALUID[OPAL_UID::ENTERPRISE_BANDMASTER0_UID]);
+ setband(user, band);
+ }
+ else if (!memcmp("EraseMaster", userid, 11)) {
+ set8(user, OPALUID[OPAL_UID::ENTERPRISE_ERASEMASTER_UID]);
+ }
+ else {
+ LOG(E) << "Invalid Userid " << userid;
+ return DTAERROR_INVALID_PARAMETER;
+ }
+
+ uint8_t lastRC;
+
+ if (currentHostChallenge.size() == 0 || newHostChallenge.size() == 0) {
+ string defaultPassword;
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
+ LOG(E) << "setPassword failed to retrieve MSID";
+ return lastRC;
+ }
+ const char * dps = defaultPassword.c_str();
+ uint8_t dpslen = (uint8_t)strlen(dps);
+ vector defaultHostChallenge(dps, dps+dpslen);
+ if (currentHostChallenge.size() == 0)
+ currentHostChallenge=defaultHostChallenge;
+ if (newHostChallenge.size() == 0)
+ newHostChallenge=defaultHostChallenge;
+ }
+
+ std::vector usercpin;
+ user2cpin(usercpin, user);
+
+ lastRC = WithSession([this, currentHostChallenge, user](){
+ return session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, currentHostChallenge, user);
+ },
+ [this, newHostChallenge, usercpin](){
+ vectortoken=newHostChallenge;
+ token.insert(token.begin(), (uint8_t)newHostChallenge.size());
+ token.insert(token.begin(), 0xd0);
+ return setTable(usercpin, "PIN", token);
+ });
+
+ if (lastRC == 0) {
+ LOG(I) << userid << " password changed";
+ }
+ LOG(D1) << "Exiting DtaDevEnterprise::setPassword()";
+ return lastRC;
}
+
uint8_t DtaDevEnterprise::setNewPassword_SUM(char * password, char * userid, char * newpassword)
{
LOG(D1) << "Entering DtaDevEnterprise::setNewPassword_SUM()";
- LOG(I) << "setNewPassword_SUM is not in the Enterprise SSC and not supported";
+ LOG(D) << "setNewPassword_SUM is not in the Enterprise SSC and not supported";
LOG(D1) << "Exiting DtaDevEnterprise::setNewPassword_SUM()";
return 0;
}
-uint8_t DtaDevEnterprise::setMBREnable(uint8_t mbrstate, char * Admin1Password)
+
+uint8_t DtaDevEnterprise::setMBREnable(uint8_t mbrstate, char * Admin1Password)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::setMBREnable";
+ if (NULL == Admin1Password) { LOG(E) << "This shouldn't happen " << mbrstate; }
+ LOG(D) << "MBR shadowing is optional in the Enterprise SSC and not supported";
+ LOG(D1) << "Exiting DtaDevEnterprise::setMBREnable";
+ return 0;
+}
+uint8_t DtaDevEnterprise::setMBREnable(uint8_t state, vector Admin1HostChallenge)
{
- LOG(D1) << "Entering DtaDevEnterprise::setMBREnable";
- if (NULL == Admin1Password) { LOG(E) << "This shouldn't happen " << mbrstate; }
- LOG(I) << "MBR shadowing is optional in the Enterprise SSC and not supported";
- LOG(D1) << "Exiting DtaDevEnterprise::setMBREnable";
- return 0;
+ LOG(D1) << "Entering DtaDevEnterprise::setMBREnable";
+ if (0 == Admin1HostChallenge.size()) { LOG(E) << "This shouldn't happen " << state; }
+ LOG(D) << "MBR shadowing is optional in the Enterprise SSC and not supported";
+ LOG(D1) << "Exiting DtaDevEnterprise::setMBREnable";
+ return 0;
}
+
uint8_t DtaDevEnterprise::setMBRDone(uint8_t mbrstate, char * Admin1Password)
{
- LOG(D1) << "Entering DtaDevEnterprise::setMBRDone";
- if (NULL == Admin1Password) { LOG(E) << "This shouldn't happen " << mbrstate; }
- LOG(I) << "MBR shadowing is optional in the Enterprise SSC and not supported";
- LOG(D1) << "Exiting DtaDevEnterprise::setMBRDone";
+ LOG(D1) << "Entering DtaDevEnterprise::setMBRDone";
+ if (NULL == Admin1Password) { LOG(E) << "This shouldn't happen " << mbrstate; }
+ LOG(D) << "MBR shadowing is optional in the Enterprise SSC and not supported";
+ LOG(D1) << "Exiting DtaDevEnterprise::setMBRDone";
+ return 0;
+}
+uint8_t DtaDevEnterprise::setMBRDone(uint8_t state, vector Admin1HostChallenge)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::setMBRDone";
+ if (0 == Admin1HostChallenge.size()) { LOG(E) << "This shouldn't happen " << state; }
+ LOG(D) << "MBR shadowing is optional in the Enterprise SSC and not supported";
+ LOG(D1) << "Exiting DtaDevEnterprise::setMBRDone";
+ return 0;
+}
+
+uint8_t DtaDevEnterprise::TCGreset(uint8_t mbrstate)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::TCGreset";
+
+ LOG(D1) << "Exiting DtaDevEnterprise::TCGreset";
return 0;
}
@@ -494,7 +683,7 @@ uint8_t DtaDevEnterprise::setupLockingRange(uint8_t lockingrange, uint64_t start
// look up MaxRanges
uint16_t MaxRanges;
- if ((lastRC = getMaxRanges(password, &MaxRanges)) != 0) {
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
return (lastRC);
}
if (MaxRanges == 0 || MaxRanges >= 1024)
@@ -578,7 +767,7 @@ uint8_t DtaDevEnterprise::setupLockingRange(uint8_t lockingrange, uint64_t start
}
delete set;
delete session;
- LOG(I) << "LockingRange" << (uint16_t)lockingrange << " starting block " << start <<
+ LOG(D) << "LockingRange" << (uint16_t)lockingrange << " starting block " << start <<
" for " << length << " blocks configured as unlocked range";
LOG(D1) << "Exiting DtaDevEnterprise::setupLockingRange";
return 0;
@@ -591,23 +780,22 @@ uint8_t DtaDevEnterprise::setupLockingRange_SUM(uint8_t lockingrange, uint64_t s
return 0;
}
////////////////////////////////////////////////////////////////////////////////
-uint8_t DtaDevEnterprise::listLockingRanges(char * password, int16_t rangeid)
+uint8_t DtaDevEnterprise::listLockingRanges(char * password, int16_t rangeid, uint8_t)
////////////////////////////////////////////////////////////////////////////////
{
LOG(D1) << "Entering DtaDevEnterprise::listLockingRanges";
uint8_t lastRC = 0, failRC = 0;
int one_succeeded = 0;
- string defaultPassword;
char *pwd = NULL;
// if (NULL == password) { LOG(E) << "password NULL"; }
+ string defaultPassword;
if ((password == NULL) || (*password == '\0')) {
- if ((lastRC = getDefaultPassword()) != 0) {
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
LOG(E) << __func__ << ": unable to retrieve MSID";
return lastRC;
}
- defaultPassword = response.getString(5);
pwd = (char *)defaultPassword.c_str();
} else {
pwd = password;
@@ -617,7 +805,7 @@ uint8_t DtaDevEnterprise::listLockingRanges(char * password, int16_t rangeid)
uint16_t MaxRanges;
if (rangeid == -1) {
- lastRC = getMaxRanges(password, &MaxRanges);
+ lastRC = getMaxRanges(&MaxRanges);
if (lastRC != 0)
return lastRC;
} else
@@ -671,7 +859,7 @@ uint8_t DtaDevEnterprise::listLockingRanges(char * password, int16_t rangeid)
}
if (getTable(table, "Name", "LockOnReset"))
{
- LOG(I) << " row[" << i << "] not found in LOCKING table";
+ LOG(D) << " row[" << i << "] not found in LOCKING table";
delete session;
continue;
}
@@ -757,12 +945,12 @@ uint8_t DtaDevEnterprise::listLockingRanges(char * password, int16_t rangeid)
}
uint8_t DtaDevEnterprise::setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
- char * password)
+ char * password, uint8_t)
{
LOG(D1) << "Entering DtaDevEnterprise::setLockingRange";
uint8_t lastRC;
- // convert Opal lockingstate to boolean
+ // convert Opal lockingstate to boolean
OPAL_TOKEN locked;
switch (lockingstate) {
case OPAL_LOCKINGSTATE::READWRITE:
@@ -778,11 +966,11 @@ uint8_t DtaDevEnterprise::setLockingRange(uint8_t lockingrange, uint8_t lockings
LOG(E) << "Invalid locking state for setLockingRange (RW=1, LOCKED=3)";
return DTAERROR_INVALID_PARAMETER;
}
-
+
// look up MaxRanges
uint16_t MaxRanges;
- if ((lastRC = getMaxRanges(password, &MaxRanges)) != 0) {
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
return lastRC;
}
if (MaxRanges == 0 || MaxRanges >= 1024)
@@ -845,10 +1033,94 @@ uint8_t DtaDevEnterprise::setLockingRange(uint8_t lockingrange, uint8_t lockings
}
delete set;
delete session;
- LOG(I) << "Locking range Read/Write set " << (uint16_t)locked;
+ LOG(D) << "Locking range Read/Write set " << (uint16_t)locked;
LOG(D1) << "Exiting DtaDevEnterprise::setLockingRange";
return 0;
}
+
+
+uint8_t DtaDevEnterprise::setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
+ vectorHostChallenge, uint8_t){
+ LOG(D1) << "Entering DtaDevEnterprise::setLockingRange";
+ uint8_t lastRC;
+
+ // convert Opal lockingstate to boolean
+ OPAL_TOKEN locked;
+ switch (lockingstate) {
+ case OPAL_LOCKINGSTATE::READWRITE:
+ locked = OPAL_TOKEN::OPAL_FALSE;
+ break;
+ case OPAL_LOCKINGSTATE::READONLY:
+ LOG(E) << "Read Only locking state is unsupported in Enterprise SSC";
+ return DTAERROR_INVALID_PARAMETER;
+ case OPAL_LOCKINGSTATE::LOCKED:
+ locked = OPAL_TOKEN::OPAL_TRUE;
+ break;
+ default:
+ LOG(E) << "Invalid locking state for setLockingRange (RW=1, LOCKED=3)";
+ return DTAERROR_INVALID_PARAMETER;
+ }
+
+ // look up MaxRanges
+ uint16_t MaxRanges;
+
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
+ return lastRC;
+ }
+ if (MaxRanges == 0 || MaxRanges >= 1024)
+ return DTAERROR_UNSUPORTED_LOCKING_RANGE;
+
+ // make sure lockingrange is in bounds
+ if (lockingrange > MaxRanges)
+ {
+ LOG(E) << "Requested locking range " << lockingrange << " greater than MaxRanges " << MaxRanges;
+ return DTAERROR_UNSUPORTED_LOCKING_RANGE;
+ }
+
+
+ //** BandMaster0 UID of Table 28 Locking SP Authority table, p. 70 of Enterprise SSC rev 3.00
+ vector user = vUID(OPAL_UID::ENTERPRISE_BANDMASTER0_UID);
+ setband(user, lockingrange);
+ lastRC = WithSimpleSessionCommand(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, HostChallenge, user,
+ [lockingrange, locked](DtaCommand * set){
+ //** Band0 UID of Table 33 Locking SP Locking table, p. 84 of Enterprise SSC rev 3.00
+ vector object = vUID(OPAL_UID::OPAL_LOCKINGRANGE_GLOBAL);
+ setband(object, lockingrange);
+
+ vector method;
+ set8(method, OPALMETHOD[OPAL_METHOD::ESET]);
+
+ set->reset(object, method);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTLIST);
+ set->addToken(OPAL_TOKEN::STARTNAME);
+ set->addToken("WriteLocked");
+ set->addToken(locked);
+ set->addToken(OPAL_TOKEN::ENDNAME);
+ set->addToken(OPAL_TOKEN::STARTNAME);
+ set->addToken("ReadLocked");
+ set->addToken(locked);
+ set->addToken(OPAL_TOKEN::ENDNAME);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->addToken(OPAL_TOKEN::ENDLIST);
+ set->complete();
+ });
+
+ if (lastRC != 0) {
+ LOG(E) << "DtaDevEnterprise::setLockingRange:: SET Failed ";
+ } else {
+ LOG(D) << "Locking range Read/Write set " << (uint16_t)locked;
+ LOG(D1) << "Exiting DtaDevEnterprise::setLockingRange";
+ }
+
+ return lastRC;
+}
+
+
uint8_t DtaDevEnterprise::setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
char * password) {
LOG(D1) << "Entering DtaDevEnterprise::setLockingRange_SUM()";
@@ -856,82 +1128,142 @@ uint8_t DtaDevEnterprise::setLockingRange_SUM(uint8_t lockingrange, uint8_t lock
LOG(D1) << "Exiting DtaDevEnterprise::setLockingRange_SUM()";
return DTAERROR_INVALID_PARAMETER;
}
-uint8_t DtaDevEnterprise::enableUser(char * password, char * userid, OPAL_TOKEN status)
+
+uint8_t DtaDevEnterprise::enableUser(uint8_t mbrstate, char * password, char * userid)
{
- LOG(D1) << "Entering DtaDevEnterprise::enableUser";
- LOG(E) << "enableUser not implemented";
- if (!password && !userid) { LOG(E) << "Formal Parameters"; }
- LOG(D1) << "Exiting DtaDevEnterprise::enableUser()";
- return DTAERROR_INVALID_PARAMETER;
+ LOG(D1) << "Entering DtaDevEnterprise::enableUser";
+ LOG(E) << "enableUser not implemented";
+ if (!password || !userid) { LOG(E) << "Formal Parameters"; }
+ LOG(D1) << "Exiting DtaDevEnterprise::enableUser()";
+ return DTAERROR_INVALID_PARAMETER;
}
+uint8_t DtaDevEnterprise::enableUser(uint8_t mbrstate, vector HostChallenge, char * userid)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::enableUser";
+ LOG(E) << "enableUser not implemented";
+ if (0==HostChallenge.size() || !userid) { LOG(E) << "Formal Parameters"; }
+ LOG(D1) << "Exiting DtaDevEnterprise::enableUser()";
+ return DTAERROR_INVALID_PARAMETER;
+}
+
+//uint8_t DtaDevEnterprise::enableUser(char * password, char * userid, OPAL_TOKEN status)
+//{
+// LOG(D1) << "Entering DtaDevEnterprise::enableUser";
+// LOG(E) << "enableUser not implemented";
+// if (!password || !userid) { LOG(E) << "Formal Parameters"; }
+// LOG(D1) << "Exiting DtaDevEnterprise::enableUser()";
+// return 0xff;
+//}
+uint8_t DtaDevEnterprise::enableUserRead(uint8_t mbrstate, char * password, char * userid)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::enableUserRead";
+ LOG(E) << "enableUserRead not implemented";
+ if (!password || !userid) { LOG(E) << "Formal Parameters"; }
+ LOG(D1) << "Exiting DtaDevEnterprise::enableUserRead()";
+ return 0xff;
+}
+uint8_t DtaDevEnterprise::enableUserRead(uint8_t state, vector HostChallenge, char * userid)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::enableUserRead";
+ LOG(E) << "enableUserRead not implemented";
+ if (0==HostChallenge.size() || !userid) { LOG(E) << "Formal Parameters"; }
+ LOG(D1) << "Exiting DtaDevEnterprise::enableUserRead()";
+ return 0xff;
+}
+
+
uint8_t DtaDevEnterprise::revertTPer(char * password, uint8_t PSID, uint8_t AdminSP)
{
- LOG(D1) << "Entering DtaDevEnterprise::revertTPer()";
- if (password == NULL) { LOG(D4) << "Referencing formal parameters " << PSID; }
- uint8_t lastRC;
- DtaCommand *cmd = new DtaCommand();
- if (NULL == cmd) {
- LOG(E) << "Unable to create command object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session = new DtaSession(this);
- if (NULL == session) {
- LOG(E) << "Unable to create session object ";
- delete cmd;
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- OPAL_UID uid = OPAL_UID::OPAL_SID_UID;
- if (PSID) {
- session->dontHashPwd(); // PSID pwd should be passed as entered
- uid = OPAL_UID::OPAL_PSID_UID;
- }
- if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, password, uid)) != 0) {
- delete cmd;
- delete session;
- return lastRC;
- }
+ LOG(D1) << "Entering DtaDevEnterprise::revertTPer()";
+ if (password == NULL) { LOG(D4) << "Referencing formal parameters " << PSID; }
+ uint8_t lastRC;
+ DtaCommand *cmd = new DtaCommand();
+ if (NULL == cmd) {
+ LOG(E) << "Unable to create command object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session = new DtaSession(this);
+ if (NULL == session) {
+ LOG(E) << "Unable to create session object ";
+ delete cmd;
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ OPAL_UID uid = OPAL_UID::OPAL_SID_UID;
+ if (PSID) {
+ session->dontHashPwd(); // PSID pwd should be passed as entered
+ uid = OPAL_UID::OPAL_PSID_UID;
+ }
+ if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, password, uid)) != 0) {
+ delete cmd;
+ delete session;
+ return lastRC;
+ }
if (AdminSP)
- cmd->reset(OPAL_UID::OPAL_ADMINSP_UID, OPAL_METHOD::REVERT);
+ cmd->reset(OPAL_UID::OPAL_ADMINSP_UID, OPAL_METHOD::REVERT);
else
- cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
- cmd->addToken(OPAL_TOKEN::STARTLIST);
- cmd->addToken(OPAL_TOKEN::ENDLIST);
- cmd->complete();
- session->expectAbort();
- if ((lastRC = session->sendCommand(cmd, response)) != 0) {
- delete cmd;
- delete session;
- return lastRC;
- }
- LOG(I) << "revertTper completed successfully";
- delete cmd;
- delete session;
- LOG(D1) << "Exiting DtaDevEnterprise::revertTPer()";
- return 0;
+ cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
+ cmd->addToken(OPAL_TOKEN::STARTLIST);
+ cmd->addToken(OPAL_TOKEN::ENDLIST);
+ cmd->complete();
+ session->expectAbort();
+ if ((lastRC = session->sendCommand(cmd, response)) != 0) {
+ delete cmd;
+ delete session;
+ return lastRC;
+ }
+ LOG(D) << "revertTper completed successfully";
+ delete cmd;
+ delete session;
+ LOG(D1) << "Exiting DtaDevEnterprise::revertTPer()";
+ return 0;
}
+
+uint8_t DtaDevEnterprise::revertTPer(vector HostChallenge, uint8_t PSID, uint8_t AdminSP)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::revertTPer()";
+ if (HostChallenge.size() == 0) { LOG(D4) << "Referencing formal parameters " << PSID; }
+ uint8_t lastRC = WithSimpleSessionCommand(OPAL_UID::OPAL_ADMINSP_UID, HostChallenge,
+ PSID ? OPAL_UID::OPAL_PSID_UID : OPAL_UID::OPAL_SID_UID ,
+ [this, AdminSP](DtaCommand * cmd){
+ if (AdminSP)
+ cmd->reset(OPAL_UID::OPAL_ADMINSP_UID, OPAL_METHOD::REVERT);
+ else
+ cmd->reset(OPAL_UID::OPAL_THISSP_UID, OPAL_METHOD::REVERTSP);
+ cmd->addToken(OPAL_TOKEN::STARTLIST);
+ cmd->addToken(OPAL_TOKEN::ENDLIST);
+ cmd->complete();
+ session->expectAbort();
+ });
+ if (lastRC == 0) {
+ LOG(D) << "revertTper completed successfully";
+ }
+ LOG(D1) << "Exiting DtaDevEnterprise::revertTPer()";
+ return lastRC;
+}
+
uint8_t DtaDevEnterprise::eraseLockingRange(uint8_t lockingrange, char * password)
{
uint8_t lastRC;
- string defaultPassword;
char *pwd = NULL;
LOG(D1) << "Entering DtaDevEnterprise::eraseLockingRange";
// look up MaxRanges
uint16_t MaxRanges = 0;
- if ((password == NULL) || (*password == '\0')) {
- if ((lastRC = getDefaultPassword()) != 0) {
+ string defaultPassword;
+
+ if ((password == NULL) || (*password == '\0')) {
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
LOG(E) << __func__ << ": unable to retrieve MSID";
return lastRC;
}
- defaultPassword = response.getString(5);
pwd = (char *)defaultPassword.c_str();
} else {
pwd = password;
}
- if ((lastRC = getMaxRanges(pwd, &MaxRanges)) != 0) {
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
return lastRC;
}
if (MaxRanges == 0 || MaxRanges >= 1024)
@@ -986,26 +1318,50 @@ uint8_t DtaDevEnterprise::eraseLockingRange(uint8_t lockingrange, char * passwor
}
delete erase;
delete session;
- LOG(I) << "LockingRange" << (uint16_t)lockingrange << " erased";
+ LOG(D) << "LockingRange" << (uint16_t)lockingrange << " erased";
LOG(D1) << "Exiting DtaDevEnterprise::eraseLockingRange";
return 0;
}
+uint8_t DtaDevEnterprise::activate(char * password) {
+ LOG(D1) << "Entering DtaDevEnterprise::activate() not implemented in Enterprize";
+ return 0;
+}
+uint8_t DtaDevEnterprise::getmfgstate() {
+ LOG(D1) << "Entering DtaDevEnterprise::getmfgstate() not implemented in Enterprize";
+ return 0;
+}
+uint8_t DtaDevEnterprise::getMBRsize(char * password) {
+ LOG(D1) << "Entering DtaDevEnterprise::getMBRsize() not implemented in Enterprize";
+ return 0;
+}
+
+
uint8_t DtaDevEnterprise::loadPBA(char * password, char * filename) {
LOG(D1) << "Entering DtaDevEnterprise::loadPBAimage()" << filename << " " << dev;
if (password == NULL) { LOG(D4) << "Referencing formal parameters " << filename; }
- LOG(I) << "loadPBA is not implemented. It is not a mandatory part of ";
- LOG(I) << "the enterprise SSC ";
+ LOG(D) << "loadPBA is not implemented. It is not a mandatory part of ";
+ LOG(D) << "the enterprise SSC ";
LOG(D1) << "Exiting DtaDevEnterprise::loadPBAimage()";
return DTAERROR_INVALID_PARAMETER;
}
uint8_t DtaDevEnterprise::activateLockingSP(char * password)
{
- LOG(D1) << "Entering DtaDevEnterprise::activateLockingSP()";
- if (password == NULL) { LOG(D4) << "Referencing formal parameters "; }
- LOG(E) << "activate Locking SP is not a part of the Enterprise SSC ";
- LOG(D1) << "Exiting DtaDevEnterprise::activatLockingSP()";
- return DTAERROR_INVALID_PARAMETER;
+ LOG(D1) << "Entering DtaDevEnterprise::activateLockingSP()";
+ if (password == NULL) { LOG(D4) << "Referencing formal parameters "; }
+ LOG(E) << "activate Locking SP is not a part of the Enterprise SSC ";
+ LOG(D1) << "Exiting DtaDevEnterprise::activatLockingSP()";
+ return DTAERROR_INVALID_PARAMETER;
+}
+uint8_t DtaDevEnterprise::activateLockingSP(vectorHostChallenge)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::activateLockingSP()";
+ if (0 == HostChallenge.size()) { LOG(D4) << "Referencing formal parameters "; }
+ LOG(E) << "activate Locking SP is not a part of the Enterprise SSC ";
+ LOG(D1) << "Exiting DtaDevEnterprise::activatLockingSP()";
+ return DTAERROR_INVALID_PARAMETER;
}
+
+
uint8_t DtaDevEnterprise::activateLockingSP_SUM(uint8_t lockingrange, char * password)
{
LOG(D1) << "Entering DtaDevEnterprise::activateLockingSP_SUM()";
@@ -1024,27 +1380,53 @@ uint8_t DtaDevEnterprise::eraseLockingRange_SUM(uint8_t lockingrange, char * pas
}
uint8_t DtaDevEnterprise::takeOwnership(char * newpassword)
{
- string defaultPassword;
- uint8_t lastRC;
+ uint8_t lastRC;
- LOG(D1) << "Entering DtaDevEnterprise::takeOwnership()";
- if ((lastRC = getDefaultPassword()) != 0) {
- LOG(E) << "takeOwnership failed unable to retrieve MSID";
- return lastRC;
- }
- defaultPassword = response.getString(5);
- if ((lastRC = setSIDPassword((char *)defaultPassword.c_str(), newpassword, 0)) != 0) {
- LOG(E) << "takeOwnership failed unable to set new SID password";
- return lastRC;
- }
- if ((lastRC = initLSPUsers((char *)defaultPassword.c_str(), newpassword)) != 0) {
- LOG(E) << "takeOwnership failed unable to set Locking SP user passwords";
- return lastRC;
- }
- LOG(I) << "takeOwnership complete";
- LOG(D1) << "Exiting takeOwnership()";
- return 0;
+ LOG(D1) << "Entering DtaDevEnterprise::takeOwnership()";
+ string defaultPassword;
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
+ LOG(E) << "takeOwnership failed unable to retrieve MSID";
+ return lastRC;
+ }
+ if ((lastRC = setSIDPassword((char *)defaultPassword.c_str(), newpassword, 0)) != 0) {
+ LOG(E) << "takeOwnership failed unable to set new SID password";
+ return lastRC;
+ }
+ if ((lastRC = initLSPUsers((char *)defaultPassword.c_str(), newpassword)) != 0) {
+ LOG(E) << "takeOwnership failed unable to set Locking SP user passwords";
+ return lastRC;
+ }
+ LOG(D) << "takeOwnership complete";
+ LOG(D1) << "Exiting takeOwnership()";
+ return 0;
+}
+
+uint8_t DtaDevEnterprise::takeOwnership(vector HostChallenge)
+{
+ uint8_t lastRC;
+
+ LOG(D1) << "Entering DtaDevEnterprise::takeOwnership()";
+ string defaultPassword;
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
+ LOG(E) << "takeOwnership failed unable to retrieve MSID";
+ return lastRC;
+ }
+ const char * dps = defaultPassword.c_str();
+ vector defaultHostChallenge(dps, dps+strlen(dps));
+ defaultHostChallenge.resize(8, (uint8_t)0);
+ if ((lastRC = setSIDHostChallenge(defaultHostChallenge, HostChallenge)) != 0) {
+ LOG(E) << "takeOwnership failed unable to set new SID password";
+ return lastRC;
+ }
+ if ((lastRC = initLSPUsers(const_cast(dps), HostChallenge)) != 0) {
+ LOG(E) << "takeOwnership failed unable to set Locking SP user passwords";
+ return lastRC;
+ }
+ LOG(D) << "takeOwnership complete";
+ LOG(D1) << "Exiting takeOwnership()";
+ return 0;
}
+
////////////////////////////////////////////////////////////////////////////////
uint8_t DtaDevEnterprise::setBandsEnabled(int16_t lockingrange, char * password)
////////////////////////////////////////////////////////////////////////////////
@@ -1055,7 +1437,7 @@ uint8_t DtaDevEnterprise::setBandsEnabled(int16_t lockingrange, char * password)
// look up MaxRanges
uint16_t MaxRanges = 0;
- if ((lastRC = getMaxRanges(password, &MaxRanges)) != 0) {
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
return lastRC;
}
if (MaxRanges >= 1024)
@@ -1082,15 +1464,10 @@ uint8_t DtaDevEnterprise::setBandsEnabled(int16_t lockingrange, char * password)
// get password (usually MSID)
string pwd;
const bool useMSID = password == NULL || *password == '\0';
- if (!useMSID)
- {
+ if (!useMSID) {
pwd = password;
- }
- else
- {
- if ((lastRC = getDefaultPassword()) != 0)
- return lastRC;
- pwd = response.getString(5);
+ } else if ((lastRC = getMSID(pwd)) != 0) {
+ return lastRC;
}
vector erasemaster;
@@ -1160,76 +1537,141 @@ uint8_t DtaDevEnterprise::setBandsEnabled(int16_t lockingrange, char * password)
uint8_t DtaDevEnterprise::initLSPUsers(char * defaultPassword, char * newPassword)
{
vector user, usercpin, hash, erasemaster, table;
- uint8_t lastRC;
- LOG(D1) << "Entering DtaDevEnterprise::initLSPUsers()";
+ uint8_t lastRC;
+ LOG(D1) << "Entering DtaDevEnterprise::initLSPUsers()";
// do erasemaster
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session->dontHashPwd();
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session->dontHashPwd();
set8(erasemaster, OPALUID[OPAL_UID::ENTERPRISE_ERASEMASTER_UID]);
- if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, erasemaster)) != 0) {
- delete session;
- return lastRC;
- }
- DtaHashPwd(hash, newPassword, this);
+ if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, erasemaster)) != 0) {
+ delete session;
+ return lastRC;
+ }
+ DtaHashPwd(hash, newPassword, this);
user2cpin(usercpin, erasemaster);
- if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
- LOG(E) << "Unable to set new EraseMaster password ";
- delete session;
- return lastRC;
- }
- LOG(I) << "EraseMaster password set";
- delete session;
+ if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
+ LOG(E) << "Unable to set new EraseMaster password ";
+ delete session;
+ return lastRC;
+ }
+ LOG(D) << "EraseMaster password set";
+ delete session;
// look up MaxRanges
- uint16_t MaxRanges = 0;
- if ((lastRC = getMaxRanges(NULL, &MaxRanges)) != 0) {
- return lastRC;
- }
+ uint16_t MaxRanges = 0;
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
+ return lastRC;
+ }
if (MaxRanges == 0 || MaxRanges >= 1024)
- return DTAERROR_UNSUPORTED_LOCKING_RANGE;
+ return DTAERROR_UNSUPORTED_LOCKING_RANGE;
- LOG(I) << "Maximum ranges supported " << MaxRanges;
+ LOG(I) << "Maximum ranges supported " << MaxRanges;
// do bandmasters
set8(user, OPALUID[ENTERPRISE_BANDMASTER0_UID]);
- for (uint16_t i = 0; i <= MaxRanges; i++) {
+ for (uint16_t i = 0; i <= MaxRanges; i++) {
setband(user, i);
- LOG(D3) << "initializing BandMaster" << (uint16_t) i;
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session->dontHashPwd();
- if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, user)) != 0) {
- delete session;
- // We only return failure if we fail to set BandMaster0.
- if (i == 0) {
- return lastRC;
- } else {
- continue;
- }
- }
- DtaHashPwd(hash, newPassword, this);
+ LOG(D3) << "initializing BandMaster" << (uint16_t) i;
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session->dontHashPwd();
+ if ((lastRC = session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, user)) != 0) {
+ delete session;
+ // We only return failure if we fail to set BandMaster0.
+ if (i == 0) {
+ return lastRC;
+ } else {
+ continue;
+ }
+ }
+ DtaHashPwd(hash, newPassword, this);
user2cpin(usercpin, user);
- if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
- LOG(E) << "Unable to set BandMaster" << (uint16_t) i << " new password ";
- // We only return failure if we fail to set BandMaster0.
- if (i == 0) {
- delete session;
- return lastRC;
- }
- } else {
- LOG(I) << "BandMaster" << (uint16_t) i << " password set";
- }
- delete session;
- }
- LOG(D1) << "Exiting DtaDevEnterprise::initLSPUsers()";
- return 0;
+ if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
+ LOG(E) << "Unable to set BandMaster" << (uint16_t) i << " new password ";
+ // We only return failure if we fail to set BandMaster0.
+ if (i == 0) {
+ delete session;
+ return lastRC;
+ }
+ } else {
+ LOG(I) << "BandMaster" << (uint16_t) i << " password set";
+ }
+ delete session;
+ }
+ LOG(D1) << "Exiting DtaDevEnterprise::initLSPUsers()";
+ return 0;
}
+
+uint8_t DtaDevEnterprise::initLSPUsers(char * defaultPassword, vector HostChallenge)
+{
+ uint8_t lastRC;
+ LOG(D1) << "Entering DtaDevEnterprise::initLSPUsers()";
+
+// do erasemaster
+ vector erasemaster, usercpin;
+ set8(erasemaster, OPALUID[OPAL_UID::ENTERPRISE_ERASEMASTER_UID]);
+ user2cpin(usercpin, erasemaster);
+
+ lastRC = WithSession([this, defaultPassword, erasemaster](){
+ session->dontHashPwd();
+ return session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, erasemaster);
+ },
+ [this, usercpin, HostChallenge](){
+ return setTable(usercpin, "PIN", HostChallenge);
+ });
+
+ if (lastRC != 0) {
+ LOG(E) << "Unable to set new EraseMaster host challenge ";
+ return lastRC;
+ }
+ LOG(D) << "EraseMaster host challenge set";
+
+
+ // look up MaxRanges
+ uint16_t MaxRanges = 0;
+ if ((lastRC = getMaxRanges(&MaxRanges)) != 0) {
+ return lastRC;
+ }
+ if (MaxRanges == 0 || MaxRanges >= 1024)
+ return DTAERROR_UNSUPORTED_LOCKING_RANGE;
+
+ LOG(I) << "Maximum ranges supported " << MaxRanges;
+// do bandmasters
+ vector user;
+ set8(user, OPALUID[ENTERPRISE_BANDMASTER0_UID]);
+ for (uint16_t i = 0; i <= MaxRanges; i++) {
+ LOG(D3) << "initializing BandMaster" << (uint16_t) i;
+ setband(user, i);
+ user2cpin(usercpin, user);
+
+ lastRC = WithSession([this, defaultPassword, user](){
+ session->dontHashPwd();
+ return session->start(OPAL_UID::ENTERPRISE_LOCKINGSP_UID, defaultPassword, user);
+ },
+ [this, usercpin, HostChallenge](){
+ return setTable(usercpin, "PIN", HostChallenge);
+ });
+
+ if (lastRC != 0) {
+ LOG(E) << "Unable to set BandMaster" << (uint16_t) i << " host challenge ";
+ // We only return failure if we fail to set BandMaster0.
+ if (i == 0) {
+ return lastRC;
+ }
+ } else {
+ LOG(I) << "BandMaster" << (uint16_t) i << " host challenge set";
+ }
+ }
+ LOG(D1) << "Exiting DtaDevEnterprise::initLSPUsers()";
+ return 0;
+}
+
uint8_t DtaDevEnterprise::getDefaultPassword()
{
LOG(D1) << "Entering DtaDevEnterprise::getDefaultPassword()";
@@ -1260,82 +1702,122 @@ uint8_t DtaDevEnterprise::getDefaultPassword()
}
uint8_t DtaDevEnterprise::printDefaultPassword()
{
- const uint8_t rc = getDefaultPassword();
+ string defaultPassword;
+ const uint8_t rc = getMSID(defaultPassword);
if (rc) {
LOG(E) << "unable to retrieve MSID";
return rc;
}
- string defaultPassword = response.getString(5);
fprintf(stdout, "MSID: %s\n", (char *)defaultPassword.c_str());
return 0;
}
uint8_t DtaDevEnterprise::setSIDPassword(char * oldpassword, char * newpassword,
- uint8_t hasholdpwd, uint8_t hashnewpwd)
+ uint8_t hasholdpwd, uint8_t hashnewpwd)
{
- LOG(D1) << "Entering DtaDevEnterprise::setSIDPassword()";
- uint8_t lastRC;
+ LOG(D1) << "Entering DtaDevEnterprise::setSIDPassword()";
+ uint8_t lastRC;
- vector user;
+ vector user;
set8(user, OPALUID[OPAL_SID_UID]);
vector usercpin;
set8(usercpin, OPALUID[OPAL_C_PIN_SID]);
- if (*oldpassword == '\0')
- {
- if ((lastRC = getDefaultPassword()) != 0) {
- LOG(E) << "setPassword failed to retrieve MSID";
- return lastRC;
- }
- string defaultPassword = response.getString(5);
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session->dontHashPwd();
- if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, (char *)defaultPassword.c_str(), user)) != 0) {
- delete session;
- return lastRC;
- }
- }
- else
- {
- session = new DtaSession(this);
- if (session == NULL) {
- LOG(E) << "Unable to create session object ";
- return DTAERROR_OBJECT_CREATE_FAILED;
- }
- session->dontHashPwd();
- if (!hasholdpwd) session->dontHashPwd();
- if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, oldpassword, user)) != 0) {
- delete session;
- return lastRC;
- }
- }
- vector hash;
- if (hashnewpwd)
+ if (*oldpassword == '\0')
{
- DtaHashPwd(hash, newpassword, this);
- }
- else
+ string defaultPassword;
+ if ((lastRC = getMSID(defaultPassword)) != 0) {
+ LOG(E) << "setPassword failed to retrieve MSID";
+ return lastRC;
+ }
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session->dontHashPwd();
+ if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, (char *)defaultPassword.c_str(), user)) != 0) {
+ delete session;
+ return lastRC;
+ }
+ }
+ else
+ {
+ session = new DtaSession(this);
+ if (session == NULL) {
+ LOG(E) << "Unable to create session object ";
+ return DTAERROR_OBJECT_CREATE_FAILED;
+ }
+ session->dontHashPwd();
+ if (!hasholdpwd) session->dontHashPwd();
+ if ((lastRC = session->start(OPAL_UID::OPAL_ADMINSP_UID, oldpassword, user)) != 0) {
+ delete session;
+ return lastRC;
+ }
+ }
+ vector hash;
+ if (hashnewpwd)
{
- hash.push_back(0xd0);
- hash.push_back((uint8_t)strnlen(newpassword, 255));
- for (uint16_t i = 0; i < strnlen(newpassword, 255); i++)
+ 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]);
- }
- }
- if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
- LOG(E) << "Unable to set new SID password ";
- delete session;
- return lastRC;
- }
- delete session;
- LOG(D1) << "Exiting DtaDevEnterprise::setSIDPassword()";
- return 0;
+ hash.push_back(newpassword[i]);
+ }
+ }
+ if ((lastRC = setTable(usercpin, "PIN", hash)) != 0) {
+ LOG(E) << "Unable to set new SID password ";
+ delete session;
+ return lastRC;
+ }
+ delete session;
+ LOG(D1) << "Exiting DtaDevEnterprise::setSIDHostChallenge()";
+ return 0;
+}
+
+uint8_t DtaDevEnterprise::setSIDHostChallenge(vector oldHostChallenge,
+ vector newHostChallenge)
+{
+ LOG(D1) << "Entering DtaDevEnterprise::setSIDHostChallenge()";
+ vector user;
+ set8(user, OPALUID[OPAL_SID_UID]);
+
+ vector usercpin;
+ set8(usercpin, OPALUID[OPAL_C_PIN_SID]);
+
+ uint8_t lastRC = WithSession([this, oldHostChallenge, user](){
+ session->dontHashPwd();
+ if (oldHostChallenge.size() == 0)
+ {
+ string defaultPassword;
+ uint8_t rc = getMSID(defaultPassword);
+ if (rc != 0) {
+ LOG(E) << "setPassword failed to retrieve MSID";
+ return rc;
+ }
+ return session->start(OPAL_UID::OPAL_ADMINSP_UID, (char *)defaultPassword.c_str(), user);
+ }
+ else
+ {
+ return session->start(OPAL_UID::OPAL_ADMINSP_UID, oldHostChallenge, user);
+ }
+ },
+ [this, usercpin, newHostChallenge](){
+ return setTable(usercpin, "PIN", newHostChallenge);
+ });
+
+ if (lastRC != 0) {
+ LOG(E) << "Unable to set new SID password ";
+ } else {
+ LOG(D1) << "Exiting DtaDevEnterprise::setSIDHostChallenge()";
+ }
+ return lastRC;
}
+
uint8_t DtaDevEnterprise::setTable(vector table, const char *name,
OPAL_TOKEN value)
{
@@ -1343,7 +1825,7 @@ uint8_t DtaDevEnterprise::setTable(vector table, const char *name,
token.push_back((uint8_t) value);
return(setTable(table, name, token));
}
-uint8_t DtaDevEnterprise::setTable(vector table, const char *name,
+uint8_t DtaDevEnterprise::setTable(vector table, const char *name,
vector value)
{
LOG(D1) << "Entering DtaDevEnterprise::setTable";
@@ -1377,7 +1859,7 @@ uint8_t DtaDevEnterprise::setTable(vector table, const char *name,
LOG(D1) << "Leaving DtaDevEnterprise::setTable";
return 0;
}
-uint8_t DtaDevEnterprise::getTable(vector table, const char * startcol,
+uint8_t DtaDevEnterprise::getTable(vector table, const char * startcol,
const char * endcol)
{
LOG(D1) << "Entering DtaDevEnterprise::getTable";
@@ -1417,18 +1899,19 @@ uint16_t DtaDevEnterprise::comID()
uint8_t DtaDevEnterprise::exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol)
{
uint8_t rc = 0;
- OPALHeader * hdr = (OPALHeader *) cmd->getCmdBuffer();
+ DTA_Header * hdr = (DTA_Header *) cmd->getCmdBuffer();
+ LOG(D1) << "Entering DtaDevEnterprize::exec";
LOG(D3) << endl << "Dumping command buffer";
IFLOG(D) DtaAnnotatedDump(IF_SEND, cmd->getCmdBuffer(), cmd->outputBufferSize());
- IFLOG(D3) DtaHexDump(cmd->getCmdBuffer(), SWAP32(hdr->cp.length) + sizeof (OPALComPacket));
+ IFLOG(D3) DtaHexDump(cmd->getCmdBuffer(), SWAP32(hdr->cp.length) + sizeof (DTA_ComPacketHeader));
rc = sendCmd(IF_SEND, protocol, comID(), cmd->getCmdBuffer(), cmd->outputBufferSize());
if (0 != rc) {
- LOG(E) << "Command failed on send " << (uint16_t) rc;
+ LOG(E) << "DtaDevEnterprize::exec Command failed on send " << (uint16_t) rc;
return rc;
}
- hdr = (OPALHeader *) cmd->getRespBuffer();
+ hdr = (DTA_Header *) cmd->getRespBuffer();
do {
- //LOG(I) << "read loop";
+ //LOG(D) << "read loop";
osmsSleep(25);
memset(cmd->getRespBuffer(), 0, MIN_BUFFER_LENGTH);
rc = sendCmd(IF_RECV, protocol, comID(), cmd->getRespBuffer(), MIN_BUFFER_LENGTH);
@@ -1436,8 +1919,8 @@ uint8_t DtaDevEnterprise::exec(DtaCommand * cmd, DtaResponse & resp, uint8_t pro
}
while ((0 != hdr->cp.outstandingData) && (0 == hdr->cp.minTransfer));
LOG(D3) << std::endl << "Dumping reply buffer";
- IFLOG(D) DtaAnnotatedDump(IF_RECV, cmd->getRespBuffer(), SWAP32(hdr->cp.length) + sizeof (OPALComPacket));
- IFLOG(D3) DtaHexDump(cmd->getRespBuffer(), SWAP32(hdr->cp.length) + sizeof (OPALComPacket));
+ IFLOG(D) DtaAnnotatedDump(IF_RECV, cmd->getRespBuffer(), SWAP32(hdr->cp.length) + sizeof (DTA_ComPacketHeader));
+ IFLOG(D3) DtaHexDump(cmd->getRespBuffer(), SWAP32(hdr->cp.length) + sizeof (DTA_ComPacketHeader));
if (0 != rc) {
LOG(E) << "Command failed on recv, returned " << (uint16_t) rc;
return rc;
@@ -1462,7 +1945,7 @@ uint8_t DtaDevEnterprise::properties()
}
props->addToken(OPAL_TOKEN::STARTLIST);
props->addToken(OPAL_TOKEN::STARTNAME);
- props->addToken("HostProperties");
+ props->addToken("HostProperties");
props->addToken(OPAL_TOKEN::STARTLIST);
props->addToken(OPAL_TOKEN::STARTNAME);
props->addToken("MaxComPacketSize");
@@ -1505,7 +1988,7 @@ void DtaDevEnterprise::puke()
{
LOG(D1) << "Entering DtaDevEnterprise::puke()";
- DtaDev::puke();
+ DtaDevOS::puke();
if (disk_info.Properties) {
uint32_t i = 0, j = 0;
@@ -1529,7 +2012,7 @@ void DtaDevEnterprise::puke()
j++;
if (!(j % 3)) cout << std::endl;
}
- }
+ }
}
if ((j % 3) != 0)
cout << std::endl;
@@ -1608,14 +2091,14 @@ uint8_t DtaDevEnterprise::rawCmd(char *sp, char *hexauth, char *pass,
delete session;
return lastRC;
}
- LOG(I) << "Command:";
+ LOG(D) << "Command:";
cmd->dumpCommand();
if ((lastRC = session->sendCommand(cmd, response)) != 0) {
delete cmd;
delete session;
return lastRC;
}
- LOG(I) << "Response:";
+ LOG(D) << "Response:";
cmd->dumpResponse();
delete cmd;
delete session;
@@ -1627,17 +2110,17 @@ uint8_t DtaDevEnterprise::objDump(char *sp, char * auth, char *pass,
{
LOG(D1) << "Entering DtaDevEnterprise::objDump";
LOG(D1) << sp << " " << auth << " " << pass << " " << objID;
+ if (16 != strnlen(auth, 32)) {
+ LOG(E) << "Authority must be 16 byte ascii string of hex authority uid";
+ return 0xff;
+ }
+ if (16 != strnlen(objID, 32)) {
+ LOG(E) << "ObjectID must be 16 byte ascii string of hex object uid";
+ return 0xff;
+ }
DtaCommand *get = new DtaCommand();
vector authority, object;
uint8_t work;
- if (16 != strnlen(auth, 32)) {
- LOG(E) << "Authority must be 16 byte ascii string of hex authority uid";
- return 0xff;
- }
- if (16 != strnlen(objID, 32)) {
- LOG(E) << "ObjectID must be 16 byte ascii string of hex object uid";
- return 0xff;
- }
authority.push_back(OPAL_SHORT_ATOM::BYTESTRING8);
for (uint32_t i = 0; i < 16; i += 2) {
work = auth[i] & 0x40 ? 16 * ((auth[i] & 0xf) + 9) : 16 * (auth[i] & 0x0f);
@@ -1657,7 +2140,7 @@ uint8_t DtaDevEnterprise::objDump(char *sp, char * auth, char *pass,
get->addToken(OPAL_TOKEN::ENDLIST);
get->addToken(OPAL_TOKEN::ENDLIST);
get->complete();
- LOG(I) << "Command:";
+ LOG(D) << "Command:";
get->dumpCommand();
session = new DtaSession(this);
if (session->start((OPAL_UID)atoi(sp), pass, authority)) {
@@ -1670,7 +2153,7 @@ uint8_t DtaDevEnterprise::objDump(char *sp, char * auth, char *pass,
delete session;
return 0xff;
}
- LOG(I) << "Response:";
+ LOG(D) << "Response:";
get->dumpResponse();
delete get;
delete session;
@@ -1680,3 +2163,15 @@ uint8_t DtaDevEnterprise::objDump(char *sp, char * auth, char *pass,
#ifdef _MSC_VER
#pragma warning(pop)
#endif
+
+
+uint8_t DtaDevEnterprise::getMSID(string& MSID) {
+ const uint8_t rc = getDefaultPassword();
+ if (rc) {
+ LOG(E) << "unable to read MSID password";
+ return rc;
+ }
+ MSID = response.getString(5);
+ LOG(D1) << "MSID=" << MSID;
+ return 0;
+}
diff --git a/Common/DtaDevEnterprise.h b/Common/DtaDevEnterprise.h
index 5350da5c..1add23db 100644
--- a/Common/DtaDevEnterprise.h
+++ b/Common/DtaDevEnterprise.h
@@ -1,23 +1,23 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
-This software is Copyright 2017 Spectra Logic Corporation
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+ This software is Copyright 2017 Spectra Logic Corporation
-This file is part of sedutil.
+ 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 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.
+ 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 .
+ You should have received a copy of the GNU General Public License
+ along with sedutil. If not, see .
- * C:E********************************************************************** */
+ * C:E********************************************************************** */
#pragma once
class DtaCommand;
class DtaSession;
@@ -33,181 +33,300 @@ class DtaSession;
using namespace std;
/** Device Class represents a disk device, conforming to the TCG Enterprise standard
-*/
+ */
class DtaDevEnterprise : public DtaDevOS {
public:
- /** Constructor using an OS specific device descriptor.
- * @param devref reference to device is OS specific lexicon
- * */
- DtaDevEnterprise(const char * devref);
- /** Default destructor, does nothing*/
- ~DtaDevEnterprise();
- /** Inform TPer of the communication propertied I wiah to use and
- * receive the TPer maximum values
- */
- uint8_t properties();
- /** Send a command to the device and wait for the response
- * @param cmd the DtaCommand object containg the command
- * @param response the DtaResonse object containing the response
- * @param protocol The security protocol number to use for the command
- */
- uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 0x01);
- /** return the communications ID to be used for sessions to this device */
- uint16_t comID();
- /** Change the SID password from it's MSID default
- * @param newpassword new password for SID
- */
- uint8_t takeOwnership(char * newpassword);
- /** Change the passwords for the enabled Bandmasters and the Erasemaster
- * from the MSID default.
- * @param defaultPassword the MSID password
- * @param newPassword the nesw password to be set
- * */
- uint8_t initLSPUsers(char * defaultPassword, char * newPassword);
- /** retrieve the MSID password */
- uint8_t printDefaultPassword();
- /** retrieve a single row from a table
- * @param table the UID of the table
- * @param startcol the starting column of data requested
- * @param endcol the ending column of the data requested
- */
- uint8_t getTable(vector table, const char * startcol,
- const char * endcol);
- /** 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
- */
- uint8_t setSIDPassword(char * oldpassword, char * newpassword,
- uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1);
- /** set a single column in an object table
- * @param table the UID of the table
- * @param name the column name to be set
- * @param value data to be stored the the column
- */
- uint8_t setTable(vector table, const char *name,
- vector value);
- /** set a single column in a table
- * @param table the UID of the table
- * @param name the column name to be set
- * @param value data to be stored the the column
- */
- uint8_t setTable(vector table, const char *name,
- OPAL_TOKEN value);
- /** dummy code not implemented the the enterprise SSC */
- uint8_t activateLockingSP(char * password);
- /** dummy code not implemented in teh enterprise SSC*/
- uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password);
- /** dummy code not implemented in teh enterprise SSC*/
- uint8_t eraseLockingRange_SUM(uint8_t lockingrange, char * password);
- /** dummy code not implemented in teh enterprise SSC*/
- uint8_t revertLockingSP(char * password, uint8_t keep = 0);
- /** get the UID or CPIN ID of a user from their character name*/
- uint8_t getAuth4User(char * userid, uint8_t column, std::vector &userData);
- /** Enable a Bandmaster Not functional */
- uint8_t enableUser(char * password, char * userid, OPAL_TOKEN status = OPAL_TOKEN::OPAL_TRUE);
- /** Primitive to set the MBRDone flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- uint8_t setMBRDone(uint8_t state, char * Admin1Password);
- /** Primitive to set the MBREnable flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- uint8_t setMBREnable(uint8_t state, char * Admin1Password);
-
- /** 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
- */
- uint8_t setPassword(char * password, char * userid, char * newpassword);
- /** dummy code not implemented in the enterprise SSC*/
- uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword);
- uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
- char * password);
- /** dummy code not implemented in the enterprise SSC*/
- uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
- char * password);
- /** Setup a locking range. Initialize a locking range, set it's start
- * LBA and length, initialize it as unlocked with locking disabled.
- * @param lockingrange The Locking Range to be setup
- * @param start Starting LBA
- * @param length Number of blocks
- * @param password Password of administrator
- */
- uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password);
- /** dummy code not implemented in the enterprise SSC*/
- uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password);
- /** List status of locking ranges.
- * @param password Password of administrator
- */
- uint8_t listLockingRanges(char * password, int16_t rangeid);
- /** Change the active state of a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param enabled enable (true) or disable (false) the lockingrange
- * @param password password of administrative authority for locking range
- */
- uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled, char * password);
- /** Generate a new encryption key for a locking range.
- * @param lockingrange locking range number
- * @param password password of the locking administrative authority
- */
- uint8_t rekeyLockingRange(uint8_t lockingrange, char * password);
- uint8_t setBandsEnabled(int16_t lockingrange, char * password);
- /** Reset the TPER to its factory condition
- * ERASES ALL DATA!
- * @param password password of authority (SID or PSID)
- * @param PSID true or false is the authority the PSID
- * */
- uint8_t revertTPer(char * password, uint8_t PSID = 0, uint8_t AdminSP = 0);
- /** Erase a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param password Password of administrative authority for locking range
- */
- uint8_t eraseLockingRange(uint8_t lockingrange, char * password);
- /** 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
- */
- uint8_t loadPBA(char * password, char * filename);
- /** 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
- */
- uint8_t initialSetup(char * password);
- /** 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);
- /** Displays the identify and discovery 0 information */
- void puke();
- /** Dumps an object for diagnostic purposes
- * @param sp index into the OPALUID table for the SP the object is in
- * @param auth the authority ti use for the dump
- * @param pass the password for the suthority
- * @param objID the UID of the object to dump
- * */
- uint8_t objDump(char *sp, char * auth, char *pass, char * objID);
- /** Issue any command to the drive for diagnostic purposes
- * @param sp index into the OPALUID table for the SP the object is in
- * @param hexauth the authority ti use for the dump
- * @param pass the password for the suthority
- * @param hexinvokingUID caller of the method
- * @param hexmethod the method to call
- * @param hexparms the parameter list for the command
- *
- */
- uint8_t rawCmd(char *sp, char *hexauth, char *pass,
- char *hexinvokingUID, char *hexmethod, char *hexparms);
+ /** Inform TPer of the communication propertied I wiah to use and
+ * receive the TPer maximum values
+ */
+ uint8_t properties();
+ /** Send a command to the device and wait for the response
+ * @param cmd the DtaCommand object containg the command
+ * @param resp the DtaResonse object containing the response
+ * @param protocol The security protocol number to use for the command
+ */
+ uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 0x01);
+ /** return the communications ID to be used for sessions to this device */
+ uint16_t comID();
+ /** Change the SID password from its MSID default
+ * @param newpassword new password for SID
+ */
+ uint8_t takeOwnership(char * newpassword);
+ /** Change the SID HostChallenge from its MSID default
+ * @param HostChallenge new HostChallenge for SID
+ */
+ uint8_t takeOwnership(vector HostChallenge);
+
+ /** Change the passwords for the enabled Bandmasters and the Erasemaster
+ * from the MSID default.
+ * @param defaultPassword the MSID password
+ * @param newPassword the nesw password to be set
+ */
+ uint8_t initLSPUsers(char * defaultPassword, char * newPassword);
+
+ /** Change the passwords for the enabled Bandmasters and the Erasemaster
+ * from the MSID default.
+ * @param defaultPassword the MSID password
+ * @param HostChallenge the new HostChallenge to be set
+ */
+ uint8_t initLSPUsers(char * defaultPassword, vector HostChallenge);
+
+ /** retrieve the MSID password */
+ uint8_t printDefaultPassword();
+ /** retrieve a single row from a table
+ * @param table the UID of the table
+ * @param startcol the starting column of data requested
+ * @param endcol the ending column of the data requested
+ */
+ uint8_t getTable(vector table, const char * startcol,
+ const char * endcol);
+ /** 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
+ */
+ uint8_t setSIDPassword(char * oldpassword, char * newpassword,
+ uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1);
+
+ /** Set the SID password.
+ * @param oldHostChallenge current SID host challenge
+ * @param newHostChallenge value host challenge is to be changed to
+ * @note neither value is hashed
+ */
+ uint8_t setSIDHostChallenge(vector oldHostChallenge,
+ vector newHostChallenge);
+ /** set a single column in an object table
+ * @param table the UID of the table
+ * @param name the column name to be set
+ * @param value data to be stored the the column
+ */
+ uint8_t setTable(vector table, const char *name,
+ vector value);
+ /** set a single column in a table
+ * @param table the UID of the table
+ * @param name the column name to be set
+ * @param value data to be stored the the column
+ */
+ uint8_t setTable(vector table, const char *name,
+ OPAL_TOKEN value);
+ /** dummy code not implemented the the enterprise SSC */
+ uint8_t activateLockingSP(char * password);
+
+ /** Enable locking on the device
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ uint8_t activateLockingSP(vectorHostChallenge);
+
+ /** dummy code not implemented in teh enterprise SSC*/
+ uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password);
+ /** dummy code not implemented in teh enterprise SSC*/
+ uint8_t eraseLockingRange_SUM(uint8_t lockingrange, char * password);
+
+ /** Restore the state of the Locking SP to factory defaults.
+ * Enables locking
+ * @param password current SID password
+ * @param keep boolean keep the data (NOT FUNCTIONAL)
+ */
+ uint8_t revertLockingSP(char * password, uint8_t keep = 0);
+
+ /** Reset the Locking SP to its factory default condition
+ * ERASES ALL DATA!
+ * @param HostChallenge of Administrative user
+ * @param keep true false for noerase function NOT WWORKING
+ */
+ uint8_t revertLockingSP(vector HostChallenge, uint8_t keep = 0);
+
+ /** get the UID or CPIN ID of a user from their character name*/
+ uint8_t getAuth4User(char * userid, uint8_t column, std::vector &userData);
+ // /** Enable a Bandmaster Not functional */
+ // uint8_t enableUser(char * password, char * userid, OPAL_TOKEN status = OPAL_TOKEN::OPAL_TRUE);
+ uint8_t enableUser(uint8_t mbrstate, char * password, char * userid);
+ uint8_t enableUserRead(uint8_t mbrstate, char * password, char * userid);
+
+ /** enable a locking sp user.
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of locking sp administrative authority
+ * @param userid the user to be enabled
+ */
+ uint8_t enableUser(uint8_t state, vector HostChallenge, char * userid);
+
+ /** Enable locking on the device
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ uint8_t enableUserRead(uint8_t state, vector HostChallenge, char * userid);
+
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1Password Locking SP authority with access to flag
+ */
+ uint8_t setMBRDone(uint8_t state, char * Admin1Password);
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ uint8_t setMBRDone(uint8_t state, vector Admin1HostChallenge);
+
+ uint8_t TCGreset(uint8_t mbrstate);
+
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1Password Locking SP authority with access to flag
+ */
+ uint8_t setMBREnable(uint8_t state, char * Admin1Password);
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ uint8_t setMBREnable(uint8_t state, vector Admin1HostChallenge);
+
+
+ /** 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
+ */
+ uint8_t setPassword(char * password, char * userid, char * newpassword, uint8_t idx=0);
+
+ /** Set the host challenge of a locking SP user.
+ * @param currentHostChallenge current host challenge
+ * @param userid the userid whose host challenge is to be changed
+ * @param newHostChallenge value host challenge is to be changed to
+ */
+ uint8_t setHostChallenge(vector currentHostChallenge, char * userid,
+ vector newHostChallenge, uint8_t idx=0);
+
+
+
+ /** dummy code not implemented in the enterprise SSC*/
+ uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword);
+ uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
+ char * password, uint8_t idx=0);
+ uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
+ vectorHostChallenge, uint8_t idx=0);
+ /** dummy code not implemented in the enterprise SSC*/
+ uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate, char * password);
+ /** Setup a locking range. Initialize a locking range, set its start
+ * LBA and length, initialize it as unlocked with locking disabled.
+ * @param lockingrange The Locking Range to be setup
+ * @param start Starting LBA
+ * @param length Number of blocks
+ * @param password Password of administrator
+ */
+ uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password);
+ /** dummy code not implemented in the enterprise SSC*/
+ uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password);
+ /** List status of locking ranges.
+ * @param password Password of administrator
+ */
+ uint8_t listLockingRanges(char * password, int16_t rangeid, uint8_t idx=0);
+ /** Change the active state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param enabled enable (true) or disable (false) the lockingrange
+ * @param password password of administrative authority for locking range
+ */
+ uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled, char * password, uint8_t idx=0);
+
+ /** User command to enable/disable a locking range.
+ * RW|RO|LK are the supported states @see OPAL_LOCKINGSTATE
+ * @param lockingrange locking range number
+ * @param enabled boolean true = enabled, false = disabled
+ * @param HostChallenge HostChallenge of the locking administrative authority
+ */
+ uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
+ vector HostChallenge, uint8_t idx=0);
+
+ /** Generate a new encryption key for a locking range.
+ * @param lockingrange locking range number
+ * @param password password of the locking administrative authority
+ */
+ uint8_t rekeyLockingRange(uint8_t lockingrange, char * password);
+ uint8_t setBandsEnabled(int16_t lockingrange, char * password);
+ /** Reset the TPER to its factory condition
+ * ERASES ALL DATA!
+ * @param password password of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * */
+ uint8_t revertTPer(char * password, uint8_t PSID = 0, uint8_t AdminSP = 0);
+
+ /** Reset the TPER to its factory condition
+ * @param HostChallenge HostChallenge of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * @param AdminSP true or false is the SP the AdminSP or ThisSP (Enterprise Only)
+ */
+ uint8_t revertTPer(vector HostChallenge, uint8_t PSID = 0, uint8_t AdminSP = 0 );
+
+ /** Erase a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param password Password of administrative authority for locking range
+ */
+ uint8_t eraseLockingRange(uint8_t lockingrange, char * password);
+ uint8_t activate(char * password);
+ uint8_t getmfgstate(void);
+ uint8_t getMBRsize(char * password);
+ /** 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
+ */
+ uint8_t loadPBA(char * password, char * filename);
+ /** 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
+ */
+ uint8_t initialSetup(char * password);
+
+ /** User command to prepare the device for management by sedutil.
+ * Specific to the SSC that the device supports
+ * @param HostChallenge the HostChallenge that is to be assigned to the SSC master entities
+ */
+ uint8_t initialSetup(vectorHostChallenge);
+
+ /** 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);
+ /** Displays the identify and discovery 0 information */
+ void puke();
+ /** Dumps an object for diagnostic purposes
+ * @param sp index into the OPALUID table for the SP the object is in
+ * @param auth the authority ti use for the dump
+ * @param pass the password for the suthority
+ * @param objID the UID of the object to dump
+ * */
+ uint8_t objDump(char *sp, char * auth, char *pass, char * objID);
+ /** Issue any command to the drive for diagnostic purposes
+ * @param sp index into the OPALUID table for the SP the object is in
+ * @param hexauth the authority ti use for the dump
+ * @param pass the password for the suthority
+ * @param hexinvokingUID caller of the method
+ * @param hexmethod the method to call
+ * @param hexparms the parameter list for the command
+ *
+ */
+ uint8_t rawCmd(char *sp, char *hexauth, char *pass,
+ char *hexinvokingUID, char *hexmethod, char *hexparms);
+
+ /** Primitive to extract the MSID into a std::string
+ * @param MSID the string to receive the MSID
+ */
+ uint8_t getMSID(string& MSID);
+
+ // /** Short-circuit routine re-uses initialized drive and disk_info */
+ DtaDevEnterprise(const char * devref, DtaDevOSDrive * drive, DTA_DEVICE_INFO& di)
+ : DtaDevOS(devref, drive, di)
+ {} ;
+
+ /** Default destructor, does nothing*/
+ ~DtaDevEnterprise(){};
protected:
- uint8_t getDefaultPassword();
+ uint8_t getDefaultPassword();
private:
- uint8_t getMaxRanges(char * password, uint16_t *maxRanges);
- uint8_t getMaxRangesOpal(char * password, uint16_t *maxRanges);
+ uint8_t getMaxRanges(uint16_t *maxRanges);
+ uint8_t getMaxRangesOpal(uint16_t *maxRanges);
};
diff --git a/Common/DtaDevFactory.cpp b/Common/DtaDevFactory.cpp
new file mode 100644
index 00000000..05b96576
--- /dev/null
+++ b/Common/DtaDevFactory.cpp
@@ -0,0 +1,77 @@
+/* C:B**************************************************************************
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+ 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 "DtaDev.h"
+#include "DtaDevOS.h"
+
+
+/** Factory functions
+ *
+ * Static class member that passes through DtaDev instantiaion to DtaDevOS.
+ *
+ */
+
+
+uint8_t DtaDev::getDtaDev(const char * devref, DtaDev * & device, bool genericIfNotTPer)
+{
+ DtaDevOS * d;
+ uint8_t result = DtaDevOS::getDtaDevOS(devref, &d, genericIfNotTPer);
+ if (result == DTAERROR_SUCCESS) {
+ device = static_cast(d);
+ }
+ return result;
+}
+
+
+
+#include "log.h"
+#include "DtaDevOpal1.h"
+#include "DtaDevOpal2.h"
+#include "DtaDevEnterprise.h"
+#include "DtaDevGeneric.h"
+
+
+
+/** Factory functions
+ *
+ * Static class members that support instantiation of subclass members
+ * with the subclass switching logic localized here for easier maintenance.
+ *
+ * This method is invoked after the instantiation process for `drive`
+ * has initialized it and filled out the device information in `di`.
+ */
+
+
+DtaDevOS* DtaDevOS::getDtaDevOS(const char * devref,
+ DtaDevOSDrive * drive,
+ DTA_DEVICE_INFO & di,
+ bool genericIfNotTPer) {
+ if (DTAERROR_SUCCESS == drive->discovery0(di)) { // drive responds to most basic IF_RECV
+ if (di.OPAL20) return new DtaDevOpal2(devref, drive, di);
+ if (di.OPAL10) return new DtaDevOpal1(devref, drive, di);
+ if (di.Enterprise) return new DtaDevEnterprise(devref, drive, di);
+ // if (di.RUBY) ... etc.
+ }
+ if (genericIfNotTPer) return new DtaDevGeneric(devref, drive, di);
+
+ LOG(E) << "Unknown OPAL SSC ";
+ return NULL;
+}
diff --git a/Common/DtaDevGeneric.cpp b/Common/DtaDevGeneric.cpp
index 6f5d57c6..4785952e 100644
--- a/Common/DtaDevGeneric.cpp
+++ b/Common/DtaDevGeneric.cpp
@@ -1,5 +1,5 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+This software is Copyright (c) 2014-2024 Bright Plaza Inc.
This file is part of sedutil.
@@ -24,6 +24,8 @@ along with sedutil. If not, see .
#include "os.h"
#include
+#include
+
#include
#include
#include
@@ -39,10 +41,15 @@ along with sedutil. If not, see .
using namespace std;
-/** Class representing a disk device, this class is intended to be used when
- * it is not yet known if the device is OPAL compliant
+
+/** Class representing a disk device, this class was previously intended to be used when
+ * it was not yet known if the device was a TPer. Now it is used as a default instead of
+ * returning NULL from functions which otherwise would.
*/
+DtaDevGeneric::~DtaDevGeneric(){};
+
+
#define voidNOCODE(name, ...) void DtaDevGeneric::name(##__VA_ARGS__) { \
LOG(E) << "Generic Device class does not support function " << #name << std::endl; \
}
@@ -51,52 +58,67 @@ LOG(E) << "Generic Device class does not support function " << #name << std::end
return 0xff; \
}
-DtaDevGeneric::DtaDevGeneric(const char * devref)
-{
- DtaDevOS::init(devref);
-}
-DtaDevGeneric::~DtaDevGeneric()
-{
-}
-void DtaDevGeneric::init(const char * devref)
-{
-}
uint8NOCODE(initialSetup, char *password)
-uint8NOCODE(configureLockingRange,uint8_t lockingrange,
- uint8_t enabled, char * password)
+uint8NOCODE(initialSetup, vectorHostChallenge)
+uint8NOCODE(configureLockingRange,uint8_t lockingrange,
+ uint8_t enabled, char * password, uint8_t idx)
+uint8NOCODE(configureLockingRange,uint8_t lockingrange,
+ uint8_t enabled, vector HostChallenge, uint8_t idx)
uint8NOCODE(revertLockingSP,char * password, uint8_t keep)
+uint8NOCODE(revertLockingSP,vector HostChallenge, 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(setPassword,char * password, char * userid, char * newpassword, uint8_t idx)
+uint8NOCODE(setHostChallenge,vector oldHostChallenge, char * userid, vector newHostChallenge, uint8_t idx)
uint8NOCODE(setNewPassword_SUM,char * password, char * userid, char * newpassword)
uint8NOCODE(setMBREnable,uint8_t mbrstate, char * Admin1Password)
+uint8NOCODE(setMBREnable,uint8_t mbrstate, vector Admin1HostChallenge)
uint8NOCODE(setMBRDone,uint8_t mbrstate, char * Admin1Password)
+uint8NOCODE(setMBRDone,uint8_t mbrstate, vector Admin1HostChallenge)
+uint8NOCODE(TCGreset, uint8_t mbrstate)
uint8NOCODE(setLockingRange,uint8_t lockingrange, uint8_t lockingstate,
- char * Admin1Password)
+ char * Admin1Password, uint8_t idx)
+uint8NOCODE(setLockingRange,uint8_t lockingrange, uint8_t lockingstate,
+ vector Admin1HostChallenge, uint8_t idx)
uint8NOCODE(setLockingRange_SUM, uint8_t lockingrange, uint8_t lockingstate,
char * password)
uint8NOCODE(setupLockingRange,uint8_t lockingrange, uint64_t start,
uint64_t length, char * password)
-uint8NOCODE(listLockingRanges, char * password, int16_t rangeid)
+uint8NOCODE(listLockingRanges, char * password, int16_t rangeid, uint8_t idx)
uint8NOCODE(setupLockingRange_SUM, uint8_t lockingrange, uint64_t start,
uint64_t length, char * password)
uint8NOCODE(rekeyLockingRange, uint8_t lockingrange, char * password)
uint8NOCODE(setBandsEnabled, int16_t lockingrange, char * password)
-uint8NOCODE(enableUser,char * password, char * userid, OPAL_TOKEN status)
+
+//-0uint8NOCODE(enableUser,char * password, char * userid, OPAL_TOKEN status)
+uint8NOCODE(enableUser, uint8_t state, char * password, char * userid)
+uint8NOCODE(enableUser, uint8_t state, vector HostChallenge, char * userid)
+uint8NOCODE(enableUserRead, uint8_t state, char * password, char * userid)
+uint8NOCODE(enableUserRead, uint8_t state, vector HostChallenge, char * userid)
uint8NOCODE(revertTPer,char * password, uint8_t PSID, uint8_t AdminSP)
+uint8NOCODE(revertTPer,vector HostChallenge, uint8_t PSID, uint8_t AdminSP)
uint8NOCODE(eraseLockingRange,uint8_t lockingrange, char * password)
-uint8NOCODE(printDefaultPassword);
+uint8NOCODE(getMSID,string& MSID)
+uint8NOCODE(printDefaultPassword)
+uint8NOCODE(activate, char * password)
+uint8NOCODE(getmfgstate)
+uint8NOCODE(getMBRsize, char * password)
uint8NOCODE(loadPBA,char * password, char * filename)
uint8NOCODE(activateLockingSP,char * password)
+uint8NOCODE(activateLockingSP,vectorHostChallenge)
uint8NOCODE(activateLockingSP_SUM,uint8_t lockingrange, char * password)
uint8NOCODE(eraseLockingRange_SUM, uint8_t lockingrange, char * password)
uint8NOCODE(takeOwnership, char * newpassword)
+uint8NOCODE(takeOwnership, vector HostChallenge)
uint8NOCODE(setSIDPassword,char * oldpassword, char * newpassword,
- uint8_t hasholdpwd, uint8_t hashnewpwd)
+ uint8_t hasholdpwd, uint8_t hashnewpwd)
+uint8NOCODE(setSIDHostChallenge,vector oldHostChallenge,
+ vector newHostChallenge)
+
uint16_t DtaDevGeneric::comID()
{
- LOG(E) << "Generic Device class does not support function " << "comID" << std::endl;
- return 0xff;
+ LOG(E) << "Generic Device class does not support function " << "comID" << std::endl;
+ return 0xff;
}
uint8NOCODE(exec,DtaCommand * cmd, DtaResponse & resp, uint8_t protocol)
diff --git a/Common/DtaDevGeneric.h b/Common/DtaDevGeneric.h
index 9f5f9752..6ac9568e 100644
--- a/Common/DtaDevGeneric.h
+++ b/Common/DtaDevGeneric.h
@@ -1,29 +1,29 @@
/* C:B**************************************************************************
-This software is Copyright 2014-2017 Bright Plaza Inc.
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
-This file is part of sedutil.
+ 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 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.
+ 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 .
+ You should have received a copy of the GNU General Public License
+ along with sedutil. If not, see .
- * C:E********************************************************************** */
+ * C:E********************************************************************** */
#pragma once
class DtaCommand;
class DtaSession;
#include "os.h"
#include "DtaDev.h"
#include "DtaDevOS.h"
-#include "DtaStructures.h"
+#include "DtaStructures.h"
#include
@@ -33,195 +33,328 @@ using namespace std;
* Most of the functions in this class are implemented to return an error as
* it is not known if the device supports a SSC
*
-*/
+ */
class DtaDevGeneric : public DtaDevOS {
public:
- /** Constructor using an OS specific device descriptor.
- * @param devref reference to device is OS specific lexicon
- * */
- DtaDevGeneric(const char * devref);
- /** Default constructor */
- ~DtaDevGeneric();
- /** OS specific initialization.
- * This function should perform the necessary authority and environment checking
- * to allow proper functioning of the program, open the device, perform an ATA
- * identify, add the fields from the identify response to the disk info structure
- * and if the device is an ATA device perform a call to Discovery0() to complete
- * the disk_info structure
- * @param devref character representation of the device is standard OS lexicon
- */
- void init(const char * devref) ;
- /* sedutil.cpp */
- /** 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
- */
- uint8_t initialSetup(char * password) ;
- /** 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
- */
- uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password);
- /** 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
- */
- uint8_t setSIDPassword(char * oldpassword, char * newpassword,
- uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) ;
- /** 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
- */
- uint8_t setPassword(char * password, char * userid, char * newpassword) ;
- /** 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
- */
- uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword) ;
- /** 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
- */
- uint8_t loadPBA(char * password, char * filename) ;
- /** Change the locking state of a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param lockingstate the locking state to set
- * @param Admin1Password password of administrative authority for locking range
- */
- uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
- char * Admin1Password) ;
- /** Change the locking state of a locking range in Single User Mode
- * @param lockingrange The number of the locking range (0 = global)
- * @param lockingstate the locking state to set
- * @param password password of user authority for the locking range
- */
- uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
- char * password);
- /** Change the active state of a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param enabled enable (true) or disable (false) the lockingrange
- * @param password password of administrative authority for locking range
- */
- uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
- char * password) ;
- /** Setup a locking range. Initialize a locking range, set it's start
- * LBA and length, initialize it as unlocked with locking disabled.
- * @paran lockingrange The Locking Range to be setup
- * @param start Starting LBA
- * @param length Number of blocks
- * @paran password Password of administrator
- */
- uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password);
- /** Setup a locking range in Single User Mode. Initialize a locking range,
- * set it's start LBA and length, initialize it as unlocked with locking enabled.
- * @paran lockingrange The Locking Range to be setup
- * @param start Starting LBA
- * @param length Number of blocks
- * @paran password Password of administrator
- */
- uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
- uint64_t length, char * password);
- /** Primitive to set the MBRDone flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- /** List status of locking ranges.
- * @param password Password of administrator
- */
- uint8_t listLockingRanges(char * password, int16_t rangeid);
- /** Generate a new encryption key for a locking range.
- * @param lockingrange locking range number
- * @param password password of the locking administrative authority
- */
- uint8_t rekeyLockingRange(uint8_t lockingrange, char * password);
- /** Enable bands using MSID.
- * @param lockingrange locking range number
- */
- uint8_t setBandsEnabled(int16_t rangeid, char * password);
- uint8_t setMBRDone(uint8_t state, char * Admin1Password) ;
- /** Primitive to set the MBREnable flag.
- * @param state 0 or 1
- * @param Admin1Password Locking SP authority with access to flag
- */
- uint8_t setMBREnable(uint8_t state, char * Admin1Password) ;
- /** enable a locking sp user.
- * @param password password of locking sp administrative authority
- * @param userid the user to be enabled
- */
- uint8_t enableUser(char * password, char * userid, OPAL_TOKEN status = OPAL_TOKEN::OPAL_TRUE) ;
- /** Enable locking on the device
- * @param password password of the admin sp SID authority
- */
- uint8_t activateLockingSP(char * password) ;
- /** Enable locking on the device in Single User Mode
- * @param lockingrange locking range to activate in SUM
- * @param password password of the admin sp SID authority
- */
- uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password);
- /** Erase a Single User Mode locking range by calling the drive's erase method
- * @param lockingrange The Locking Range to erase
- * @param password The administrator password for the drive
- */
- 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
- */
- uint8_t takeOwnership(char * newpassword) ;
- /** Reset the Locking SP to its factory default condition
- * ERASES ALL DATA!
- * @param password of Administrative user
- * @param keep true false for noerase function NOT WWORKING
- */
- uint8_t revertLockingSP(char * password, uint8_t keep ) ;
- /** Reset the TPER to its factory condition
- * ERASES ALL DATA!
- * @param password password of authority (SID or PSID)
- * @param PSID true or false is the authority the PSID
- * */
- uint8_t revertTPer(char * password, uint8_t PSID, uint8_t AdminSP ) ;
- /** Erase a locking range
- * @param lockingrange The number of the locking range (0 = global)
- * @param password Password of administrative authority for locking range
- */
- virtual uint8_t eraseLockingRange(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 ti use for the dump
- * @param pass the password for the suthority
- * @param objID the UID of the object to dump
- */
- uint8_t objDump(char *sp, char * auth, char *pass,
- char * objID) ;
- /** Issue any command to the drive for diagnostic purposes
- * @param sp index into the OPALUID table for the SP the object is in
- * @param auth the authority ti use for the dump
- * @param pass the password for the suthority
- * @param invoker caller of the method
- * @param method the method to call
- * @param plist the parameter list for the command
- *
- */
- uint8_t rawCmd(char *sp, char * auth, char *pass,
- char *invoker, char *method, char *plist) ;
- /** Read MSID
- */
- uint8_t printDefaultPassword();
- /* DtaSession.cpp */
- /** Send a command to the device and wait for the response
- * @param cmd the MswdCommand object containg the command
- * @param response the DtaResonse object containing the response
- * @param protocol The security protocol number to use for the command
- */
- uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 1) ;
- /** return the communications ID to be used for sessions to this device */
- uint16_t comID() ;
+ /** Constructor using an OS specific device descriptor.
+ * @param devref reference to device is OS specific lexicon
+ * */
+ DtaDevGeneric(const char * devref);
+
+ DtaDevGeneric(const char * devref, DtaDevOSDrive * drive, DTA_DEVICE_INFO& di)
+ : DtaDevOS(devref, drive, di)
+ {
+ } ;
+
+private:
+ /** Default destructor */
+ ~DtaDevGeneric();
+
+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
+ */
+ uint8_t initialSetup(char * password) ;
+
+ /** User command to prepare the device for management by sedutil.
+ * Specific to the SSC that the device supports
+ * @param HostChallenge the HostChallenge that is to be assigned to the SSC master entities
+ */
+ uint8_t initialSetup(vectorHostChallenge);
+
+ /** 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
+ */
+ uint8_t setup_SUM(uint8_t lockingrange, uint64_t start, uint64_t length, char *Admin1Password, char * password);
+
+ /** 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
+ */
+ uint8_t setSIDPassword(char * oldpassword, char * newpassword,
+ uint8_t hasholdpwd = 1, uint8_t hashnewpwd = 1) ;
+
+ /** Set the SID host challenge.
+ * @param oldHostChallenge current SID host challenge
+ * @param newHostChallenge value host challenge is to be changed to
+ * @note neither value is hashed
+ */
+ uint8_t setSIDHostChallenge(vector oldHostChallenge,
+ vector newHostChallenge);
+
+ /** 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
+ */
+ uint8_t setPassword(char * password, char * userid, char * newpassword, uint8_t idx=0) ;
+
+ /** Set the host challenge of a locking SP user.
+ * @param oldHostChallenge current host challenge
+ * @param userid the userid whose host challenge is to be changed
+ * @param newHostChallenge value host challenge is to be changed to
+ */
+ uint8_t setHostChallenge(vector oldHostChallenge, char * userid,
+ vector newHostChallenge, uint8_t idx=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
+ */
+ uint8_t setNewPassword_SUM(char * password, char * userid, char * newpassword) ;
+ uint8_t activate(char * password);
+ uint8_t getmfgstate(void);
+ uint8_t getMBRsize(char * password);
+
+ /** 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
+ */
+ uint8_t loadPBA(char * password, char * filename) ;
+
+ /** Change the locking state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param lockingstate the locking state to set
+ * @param Admin1Password password of administrative authority for locking range
+ */
+ uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate, char * Admin1Password, uint8_t idx=0) ;
+ /** 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
+ * @param lockingstate desired locking state (see above)
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ uint8_t setLockingRange(uint8_t lockingrange, uint8_t lockingstate,
+ vector Admin1HostChallenge, uint8_t idx=0);
+
+ /** Change the locking state of a locking range in Single User Mode
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param lockingstate the locking state to set
+ * @param password password of user authority for the locking range
+ */
+ uint8_t setLockingRange_SUM(uint8_t lockingrange, uint8_t lockingstate,
+ char * password);
+
+ /** Change the active state of a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param enabled enable (true) or disable (false) the lockingrange
+ * @param password password of administrative authority for locking range
+ */
+ uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
+ char * password, uint8_t idx=0) ;
+
+ /** User command to enable/disable a locking range.
+ * RW|RO|LK are the supported states @see OPAL_LOCKINGSTATE
+ * @param lockingrange locking range number
+ * @param enabled boolean true = enabled, false = disabled
+ * @param HostChallenge HostChallenge of the locking administrative authority
+ */
+ uint8_t configureLockingRange(uint8_t lockingrange, uint8_t enabled,
+ vector HostChallenge, uint8_t idx=0);
+
+ /** Setup a locking range. Initialize a locking range, set its start
+ * LBA and length, initialize it as unlocked with locking disabled.
+ * @paran lockingrange The Locking Range to be setup
+ * @param start Starting LBA
+ * @param length Number of blocks
+ * @paran password Password of administrator
+ */
+ uint8_t setupLockingRange(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password);
+
+ /** Setup a locking range in Single User Mode. Initialize a locking range,
+ * set its start LBA and length, initialize it as unlocked with locking enabled.
+ * @paran lockingrange The Locking Range to be setup
+ * @param start Starting LBA
+ * @param length Number of blocks
+ * @paran password Password of administrator
+ */
+ uint8_t setupLockingRange_SUM(uint8_t lockingrange, uint64_t start,
+ uint64_t length, char * password);
+
+ /** List status of locking ranges.
+ * @param password Password of administrator
+ */
+ uint8_t listLockingRanges(char * password, int16_t rangeid, uint8_t idx=0);
+
+ /** Generate a new encryption key for a locking range.
+ * @param lockingrange locking range number
+ * @param password password of the locking administrative authority
+ */
+ uint8_t rekeyLockingRange(uint8_t lockingrange, char * password);
+
+ /** Enable bands using password, or MSID if password is NULL (usual case).
+ * @param rangeid locking range number
+ * @param password password or NULL to use MSID
+ */
+ uint8_t setBandsEnabled(int16_t rangeid, char * password);
+
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1Password password of the locking sp administrative authority
+ */
+ uint8_t setMBRDone(uint8_t state, char * Admin1Password) ;
+
+ /** Primitive to set the MBRDone flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge of the locking sp administrative authority
+ */
+ uint8_t setMBRDone(uint8_t state, vector Admin1HostChallenge) ;
+
+
+
+ uint8_t TCGreset(uint8_t state);
+
+
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1Password Locking SP authority with access to flag
+ */
+ uint8_t setMBREnable(uint8_t state, char * Admin1Password) ;
+
+ /** Primitive to set the MBREnable flag.
+ * @param state 0 or 1
+ * @param Admin1HostChallenge host challenge -- unsalted password of the locking administrative authority
+ */
+ uint8_t setMBREnable(uint8_t state, vector Admin1HostChallenge);
+
+
+ // /** enable a locking sp user.
+ // * @param password password of locking sp administrative authority
+ // * @param userid the user to be enabled
+ // */
+ // uint8_t enableUser(char * password, char * userid, OPAL_TOKEN status = OPAL_TOKEN::OPAL_TRUE) ;
+ uint8_t enableUser(uint8_t state, char * password, char * userid) ;
+ uint8_t enableUserRead(uint8_t state, char * password, char * userid);
+
+ /** enable a locking sp user.
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of locking sp administrative authority
+ * @param userid the user to be enabled
+ */
+ uint8_t enableUser(uint8_t state, vector HostChallenge, char * userid);
+
+ /** Enable locking on the device
+ * @param state 0 or 1
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ uint8_t enableUserRead(uint8_t state, vector HostChallenge, char * userid);
+
+ /** Enable locking on the device
+ * @param password password of the admin sp SID authority
+ */
+ uint8_t activateLockingSP(char * password) ;
+
+ /** Enable locking on the device
+ * @param HostChallenge HostChallenge of the admin sp SID authority
+ */
+ uint8_t activateLockingSP(vectorHostChallenge);
+
+ /** Enable locking on the device in Single User Mode
+ * @param lockingrange locking range to activate in SUM
+ * @param password password of the admin sp SID authority
+ */
+ uint8_t activateLockingSP_SUM(uint8_t lockingrange, char * password);
+
+ /** Erase a Single User Mode locking range by calling the drive's erase method
+ * @param lockingrange The Locking Range to erase
+ * @param password The administrator password for the drive
+ */
+ uint8_t eraseLockingRange_SUM(uint8_t lockingrange, char * password);
+
+ /** Change the SID password from its MSID default
+ * @param newpassword new password for SID and locking SP admins
+ */
+ uint8_t takeOwnership(char * newpassword) ;
+
+ /** Change the SID HostChallenge from its MSID default
+ * @param HostChallenge new HostChallenge for SID and locking SP admins
+ */
+ uint8_t takeOwnership(vector HostChallenge);
+
+ /** Reset the Locking SP to its factory default condition
+ * ERASES ALL DATA!
+ * @param password of Administrative user
+ * @param keep true false for noerase function NOT WWORKING
+ */
+ uint8_t revertLockingSP(char * password, uint8_t keep ) ;
+
+ /** Reset the Locking SP to its factory default condition
+ * ERASES ALL DATA!
+ * @param HostChallenge of Administrative user
+ * @param keep true false for noerase function NOT WWORKING
+ */
+ uint8_t revertLockingSP(vector HostChallenge, uint8_t keep = 0);
+
+
+ /** Reset the TPER to its factory condition
+ * ERASES ALL DATA!
+ * @param password password of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * */
+ uint8_t revertTPer(char * password, uint8_t PSID, uint8_t AdminSP ) ;
+
+ /** Reset the TPER to its factory condition
+ * @param HostChallenge HostChallenge of authority (SID or PSID)
+ * @param PSID true or false is the authority the PSID
+ * @param AdminSP true or false is the SP the AdminSP or ThisSP (Enterprise Only)
+ */
+ uint8_t revertTPer(vector HostChallenge, uint8_t PSID = 0, uint8_t AdminSP = 0 );
+
+
+ /** Erase a locking range
+ * @param lockingrange The number of the locking range (0 = global)
+ * @param password Password of administrative authority for locking range
+ */
+ virtual uint8_t eraseLockingRange(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 ti use for the dump
+ * @param pass the password for the suthority
+ * @param objID the UID of the object to dump
+ */
+ uint8_t objDump(char *sp, char * auth, char *pass, char * objID) ;
+
+ /** Issue any command to the drive for diagnostic purposes
+ * @param sp index into the OPALUID table for the SP the object is in
+ * @param auth the authority ti use for the dump
+ * @param pass the password for the suthority
+ * @param invoker caller of the method
+ * @param method the method to call
+ * @param plist the parameter list for the command
+ *
+ */
+ uint8_t rawCmd(char *sp, char * auth, char *pass, char *invoker, char *method, char *plist) ;
+
+
+ /** Primitive to extract the MSID into a std::string
+ * @param MSID the string to receive the MSID
+ */
+ uint8_t getMSID(string& MSID);
+
+ /** Read MSID
+ */
+ uint8_t printDefaultPassword();
+
+
+ /** Send a command to the device and wait for the response
+ * @param cmd the MswdCommand object containg the command
+ * @param resp the DtaResonse object containing the response
+ * @param protocol The security protocol number to use for the command
+ */
+ uint8_t exec(DtaCommand * cmd, DtaResponse & resp, uint8_t protocol = 1) ;
+
+ /** return the communications ID to be used for sessions to this device */
+ uint16_t comID() ;
};
diff --git a/Common/DtaDevOS.cpp b/Common/DtaDevOS.cpp
new file mode 100644
index 00000000..b1b019a8
--- /dev/null
+++ b/Common/DtaDevOS.cpp
@@ -0,0 +1,203 @@
+/* C:B**************************************************************************
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+ 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
+#include "os.h"
+#include "log.h"
+#include
+
+#include "DtaDevOS.h"
+#include "DtaHexDump.h"
+
+
+
+/** Factory method to produce instance of appropriate subclass
+ * Note that all of DtaDevGeneric, DtaDevEnterprise, DtaDevOpal, ... derive from DtaDevOS
+ * @param devref name of the device in the OS lexicon
+ * @param pdev reference into which to store the address of the new instance
+ * @param genericIfNotTPer if true, store an instance of DtaDevGeneric for non-TPers;
+ * if false, store NULL for non-TPers
+ */
+// static
+uint8_t DtaDevOS::getDtaDevOS(const char * devref,
+ DtaDevOS * * pdev, bool genericIfNotTPer)
+{
+ // LOG(D4) << "DtaDevOS::getDtaDevOS(devref=\"" << devref << "\")";
+ DTA_DEVICE_INFO disk_info;
+ bzero(&disk_info, sizeof(disk_info));
+
+ DtaDevOSDrive * drv = DtaDevOSDrive::getDtaDevOSDrive(devref, disk_info);
+ if (drv == NULL) {
+ *pdev = NULL;
+ // LOG(D4) << "DtaDevOSDrive::getDtaDevOSDrive(\"" << devref << "\", disk_info) returned NULL";
+ if (!genericIfNotTPer) { LOG(E) << "Invalid or unsupported device " << devref; }
+ // LOG(D4) << "DtaDevOS::getDtaDevOS(devref=\"" << devref << "\") returning DTAERROR_COMMAND_ERROR";
+ return DTAERROR_COMMAND_ERROR;
+ }
+
+ *pdev = getDtaDevOS(devref, drv, disk_info, genericIfNotTPer) ;
+ if (*pdev == NULL) {
+ delete drv;
+ LOG(D4) << "getDtaDevOS(" << "\"" << devref << "\"" << ", "
+ << "drive" << ", "
+ << "disk_info" << ", "
+ << ( genericIfNotTPer ? "true" : "false" )
+ << ")"
+ << " returned NULL";
+ if (!genericIfNotTPer) { LOG(E) << "Invalid or unsupported device " << devref; }
+ LOG(D4) << "DtaDevOS::getDtaDevOS(devref=\"" << devref << "\") returning DTAERROR_COMMAND_ERROR";
+ return DTAERROR_COMMAND_ERROR;
+ }
+
+
+ LOG(D4) << "DtaDevOS::getDtaDevOS(devref=\"" << devref << "\") disk_info:";
+ IFLOG(D4) DtaHexDump(&disk_info, (int)sizeof(disk_info));
+ LOG(D4) << "DtaDevOS::getDtaDevOS(devref=\"" << devref << "\") returning DTAERROR_SUCCESS";
+ return DTAERROR_SUCCESS;
+}
+
+
+/** The Device class represents a OS generic storage device.
+ * At instantiation we determine if we create an instance of the NVMe or SATA or Scsi (SAS) derived class
+ */
+
+const unsigned long long DtaDevOS::getSize() { return disk_info.devSize; }
+
+uint8_t DtaDevOS::sendCmd(ATACOMMAND cmd, uint8_t protocol, uint16_t comID,
+ void * buffer, unsigned int bufferlen)
+{
+ if (!isOpen) return 0xfe; //disk open failed so this will too
+
+ if (NULL == drive)
+ {
+ LOG(E) << "DtaDevOS::sendCmd ERROR - unknown drive type";
+ return 0xff;
+ }
+
+ return drive->sendCmd(cmd, protocol, comID, buffer, bufferlen);
+}
+
+bool DtaDevOS::identify(DTA_DEVICE_INFO& disk_info)
+{
+ return drive->identify(disk_info)
+ && DTAERROR_SUCCESS == drive->discovery0(disk_info);
+}
+
+void DtaDevOS::osmsSleep(uint32_t ms)
+{
+ usleep(ms * 1000); //convert to microseconds
+ return;
+}
+
+
+int DtaDevOS::diskScan()
+{
+ LOG(D1) << "Entering DtaDevOS:diskScan ";
+
+ IFLOG(D1) {
+ fprintf(Output2FILE::Stream(), "Scanning for TCG SWG compliant disks (debug version, loglevel=%d)\n", CLog::Level());
+ } else {
+ fprintf(Output2FILE::Stream(), "Scanning for Opal compliant disks\n");
+ }
+
+ vector devRefs=DtaDevOSDrive::enumerateDtaDevOSDriveDevRefs();
+
+ IFLOG(D1)
+ if (devRefs.size()!=0) {
+ fprintf(Output2FILE::Stream(), " device SSC Model Number Firmware Locn World Wide Name Serial Number Vendor Manufacturer Name\n");
+ fprintf(Output2FILE::Stream(), "---------- --- ------------ ------------ -------- ----- ----- ---- ----- ------- --------- ------- --------------- -------\n");
+ }
+
+ for (string & devref:devRefs) {
+
+ DtaDevOS * dev=NULL;
+ if (DTAERROR_SUCCESS == getDtaDevOS(devref.c_str(),&dev,true) && dev!=NULL) {
+
+ fprintf(Output2FILE::Stream(), "%-11s", devref.c_str());
+ if (dev->isAnySSC()) {
+ fprintf(Output2FILE::Stream(), " %s%s%s ",
+ (dev->isOpal1() ? "1" : " "),
+ (dev->isOpal2() ? "2" : " "),
+ (dev->isEprise() ? "E" : " "));
+ } else {
+ fprintf(Output2FILE::Stream(), "%s", " No ");
+ }
+
+ const char * devType = NULL;
+ switch (dev->getDevType()) {
+ case DEVICE_TYPE_ATA:
+ devType = "ATA";
+ break;
+ case DEVICE_TYPE_SAS:
+ devType = "SAS";
+ break;
+ case DEVICE_TYPE_NVME:
+ devType = "NVME";
+ break;
+ case DEVICE_TYPE_USB:
+ devType = "USB";
+ break;
+ case DEVICE_TYPE_OTHER:
+ devType = "OTHER";
+ break;
+ default:
+ devType = "UNKNOWN";
+ }
+
+ IFLOG(D1) {
+ char WWN[19]=" "; // 18 blanks as placeholder if missing
+ vectorwwn(dev->getWorldWideName());
+ if (__is_not_all_NULs(wwn.data(), (unsigned int)wwn.size())) {
+ snprintf(WWN, 19, "%02X%02X%02X%02X%02X%02X%02X%02X %c",
+ wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7],
+ dev->isWorldWideNameSynthetic() ? '*' : ' ');
+ }
+ fprintf(Output2FILE::Stream(), "%-25.25s %-8.8s %-7.7s %18s %-20.20s %-8.8s %-30.30s\n",
+ dev->getModelNum(),
+ dev->getFirmwareRev(),
+ devType,
+ WWN,
+ dev->getSerialNum(),
+ dev->getVendorID(),
+ dev->getManufacturerName());
+
+ } else {
+ fprintf(Output2FILE::Stream(), "%-25.25s %-8.8s %-7.7s\n",
+ dev->getModelNum(),
+ dev->getFirmwareRev(),
+ devType);
+ }
+
+ delete dev;
+ dev=NULL;
+ }
+ }
+
+ printf("No more disks present -- ending scan\n");
+ LOG(D1) << "Exiting DtaDevOS::scanDisk ";
+ return 0;
+}
+
+/** Close the device reference so this object can be delete. */
+DtaDevOS::~DtaDevOS()
+{
+ LOG(D4) << "Destroying DtaDevOS";
+ if (NULL != drive)
+ delete drive;
+}
diff --git a/Common/DtaDevOS.h b/Common/DtaDevOS.h
new file mode 100644
index 00000000..99c254ed
--- /dev/null
+++ b/Common/DtaDevOS.h
@@ -0,0 +1,105 @@
+/* C:B**************************************************************************
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+ 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********************************************************************** */
+#pragma once
+#include "os.h"
+#include "log.h"
+#include "DtaDev.h"
+#include "DtaDevOSDrive.h"
+
+/** OS specific implementation of DtaDevOS.
+ */
+class DtaDevOS : public DtaDev {
+public:
+ /** Destructor */
+ ~DtaDevOS();
+
+
+ /** Factory method to produce instance of appropriate subclass
+ * Note that all of DtaDevGeneric, DtaDevEnterprise, DtaDevOpal, ... derive from DtaDevOS
+ * @param devref name of the device in the OS lexicon
+ * @param pdev pointer to location into which to store the address of the new instance
+ * @param genericIfNotTPer if true, store an instance of DtaDevGeneric for non-TPers;
+ * if false, store NULL for non-TPers
+ */
+ static uint8_t getDtaDevOS(const char * devref,
+ DtaDevOS * * pdev,
+ bool genericIfNotTPer=false);
+
+
+
+
+ /** OS specific method to send an ATA command to the device
+ * @param cmd ATA command to be sent to the device
+ * @param protocol security protocol to be used in the command
+ * @param comID communications ID to be used
+ * @param buffer input/output buffer
+ * @param bufferlen length of the input/output buffer
+ */
+ uint8_t sendCmd(ATACOMMAND cmd, uint8_t protocol, uint16_t comID,
+ void * buffer, unsigned int bufferlen);
+
+ /** A static function to scan for supported drives */
+ static int diskScan();
+
+ /** Short-circuit routine re-uses initialized drive and disk_info */
+ DtaDevOS(const char * devref, DtaDevOSDrive * drv, DTA_DEVICE_INFO & di)
+ : drive(drv)
+ {dev=devref; disk_info=di; drive=drv; isOpen=(drv!=NULL && drv->isOpen());};
+
+protected:
+ /** Minimal internal type-switching routine
+ *
+ * Checks that the drive responds to discovery0.
+ * Assumes all the identify/discovery0 information is thus in di,
+ * and that drive has a file descriptor open on devref.
+ * Just tests di SSC bits and picks DtaDevOS subclass accordingly.
+ * Otherwise return NULL, or
+ * a DtaDevGeneric instance if genericIfNotTper is true.
+ */
+ static DtaDevOS* getDtaDevOS(const char * devref,
+ DtaDevOSDrive * drive,
+ DTA_DEVICE_INFO & di,
+ bool genericIfNotTPer=false);
+
+ /** OS specific command to Wait for specified number of milliseconds
+ * @param ms number of milliseconds to wait
+ */
+ void osmsSleep(uint32_t ms);
+
+ /** OS specific routine to send an ATA identify to the device */
+ bool identify(DTA_DEVICE_INFO& disk_info);
+
+
+ /** return drive size in bytes */
+ const unsigned long long getSize();
+
+private:
+ /* Protocol-specific subclass instance -- Nvme, Scsi, Sata, ... */
+ DtaDevOSDrive *drive;
+
+ // /** Default constructor */
+ // DtaDevOS()
+ // : drive(NULL)
+ // { dev=NULL;
+ // isOpen=FALSE;
+ // bzero(&disk_info, sizeof(disk_info));
+ // assert(FALSE); // ***TODO*** this is never used
+ // };
+};
diff --git a/Common/DtaDevOSDrive.cpp b/Common/DtaDevOSDrive.cpp
new file mode 100644
index 00000000..6dd587ef
--- /dev/null
+++ b/Common/DtaDevOSDrive.cpp
@@ -0,0 +1,45 @@
+/* C:B**************************************************************************
+ This software is Copyright (c) 2014-2024 Bright Plaza Inc.
+
+ 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
+#include