Drive-Trust-Alliance / sedutil

DTA sedutil Self encrypting drive software
603 stars 233 forks source link

eraseLockingRange NOT_AUTHORIZED #392

Closed rbmv closed 2 years ago

rbmv commented 2 years ago

Hello,

I'm trying to use sedutil to manage multiple locking ranges in OPAL 2 compliant storage devices. Creating (setupLockingRange), enabling (enableLockingRange) locking/unlocking (setLockingrange) have worked fine so far.

According to the TCG and NVM Express Joint Final White Paper (2015) [1]:

I have tried to do this using sedutil, looking at the help menu I guessed it should work using --eraseLockingRange :

sedutil-cli --eraseLockingRange 1 password /dev/sda
eraseLockingRange is not implemented. It is not part of the Opal SSC

After looking at the code I noticed this function is implemented for enterprise devices, and there is a counterpart for opal devices called eraseLookingRange_SUM. It even gets parsed and called when used as a parameter:

bash-4.4# sedutil-cli --eraseLockingRange_SUM 1 password /dev/sda
method status code NOT_AUTHORIZED setLockingRange Failed

But it returns a NOT_AUTHORIZED error code (the password is correct and works fine for all other operations).

Erasing the whole disk works fine with both: sedutil-cli --revertTPer and sedutil-cli --yesIreallywanttoERASEALLmydatausingthePSID

This what my locking ranges look like:

bash-4.4# sedutil-cli --listLockingRanges password /dev/sda Locking Range Configuration for /dev/sda LR0 Begin 0 for 0 RLKEna = N WLKEna = N RLocked = Y WLocked = Y LR1 Begin 2048 for 32501760 RLKEna = Y WLKEna = Y RLocked = N WLocked = N ...

This is the drive configuration:

sedutil-cli --query /dev/sda

/dev/sda ATA HP Secure Hard Disk 1002SED7 W3P1SZAW
TPer function (0x0001) ACKNAK = N, ASYNC = N. BufferManagement = N, comIDManagement = N, Streaming = Y, SYNC = Y Locking function (0x0002) Locked = N, LockingEnabled = Y, LockingSupported = Y, MBRDone = Y, MBREnabled = Y, MediaEncrypt = Y Geometry function (0x0003) Align = Y, Alignment Granularity = 8 (4096), Logical Block size = 512, Lowest Aligned LBA = 0 SingleUser function (0x0201) ALL = N, ANY = N, Policy = Y, Locking Objects = 16 DataStore function (0x0202) Max Tables = 16, Max Size Tables = 52428800, Table size alignment = 4096 OPAL 2.0 function (0x0203) Base comID = 0x07fe, Initial PIN = 0x00, Reverted PIN = 0x00, comIDs = 2 Locking Admins = 4, Locking Users = 16, Range Crossing = N

TPer Properties: MaxMethods = 1 MaxSubpackets = 1 MaxPacketSize = 17388 MaxPackets = 1 MaxComPacketSize = 17408 MaxResponseComPacketSize = 17408 MaxSessions = 1 MaxIndTokenSize = 17352 MaxAuthentications = 24 MaxTransactionLimit = 1 DefSessionTimeout = 0 MaxSessionTimeout = 0 MinSessionTimeout = 0 DefTransTimeout = 0 MaxTransTimeout = 0 MinTransTimeout = 0 MaxComIDTime = 0

Host Properties: MaxComPacketSize = 2048 MaxPacketSize = 2028 MaxIndTokenSize = 1992 MaxPackets = 1 MaxSubpackets = 1 MaxMethods = 1

I have tried to run this command with:

I'm getting the same error code in all cases.

I have also tried with two different devices: sedutil-cli --scan
Scanning for Opal compliant disks /dev/sda 2 HP Secure Hard Disk 1002SED7 root@(none):~# sedutil-cli --scan
Scanning for Opal compliant disks /dev/nvme0 2 KXG6AZNV256G KIOXIA AGHA5101

Both devices display the same behaviour.

I tried with sedutil version 1.15.1 (commit: 358cc758948be788284d5faba46ccf4cc1813796), and sedutil version 1.20.0 (d3de8e45e06a21d31cca0046ceb16ced1ef3563a), compiled from source, Linux version. I'm getting the same result in both cases.

Does the disk need to be in a specific state before it will accept this command? Or is this simply currently unsupported? From the rundabout way I needed to invoke the function I get the feeling this may be the case. Could somebody confirm this?

Thank you very much.

[1] https://nvmexpress.org/wp-content/uploads/TCGandNVMe_Joint_White_Paper-TCG_Storage_Opal_and_NVMe_FINAL.pdf [2] Here follows the command execution with full verbosity (in case it helps):

bash-4.4# sedutil-cli -vvvv --eraseLockingRangeSUM 1 password /dev/sda
Log level set to DBG3 sedutil version : 1.20.0-dirty Creating DtaResponse() Creating DtaResponse() DtaDevOS::init /dev/sda Creating DtaDevLinuxSata::DtaDev() /dev/sda Entering DtaDev::discovery0() Entering DtaDevLinuxSata::sendCmd Dumping D0Response Entering hexDump 0000 000000bc 00000001 00000000 00000000 ................ 0010 0180005f 00590000 00000000 00000000 ...
.Y.......... 0020 00000000 00000000 00000000 00000000 ................ 0030 0001100c 11000000 00000000 00000000 ................ 0040 0002100c 3b000000 00000000 00000000 ....;........... 0050 02031010 07fe0002 00000400 10000000 ................ 0060 00000000 0201100c 00000010 04000000 ................ 0070 00000000 0202100c 00000010 03200000 ............. .. 0080 00001000 c0011018 00010001 01000000 ................ 0090 00010002 00000000 00010003 01000000 ................ 00a0 0003101c 01000000 00000000 00000200 ................ 00b0 00000000 00000008 00000000 ............ Entering DtaDev::isPresent() 1 Entering DtaDev::isAnySSC 1 Entering DtaDev::isOpal2 1 Creating DtaResponse() Creating DtaResponse() DtaDevOS::init /dev/sda Creating DtaDevLinuxSata::DtaDev() /dev/sda Entering DtaDev::discovery0() Entering DtaDevLinuxSata::sendCmd Dumping D0Response Entering hexDump 0000 000000bc 00000001 00000000 00000000 ................ 0010 0180005f 00590000 00000000 00000000 ..._.Y.......... 0020 00000000 00000000 00000000 00000000 ................ 0030 0001100c 11000000 00000000 00000000 ................ 0040 0002100c 3b000000 00000000 00000000 ....;........... 0050 02031010 07fe0002 00000400 10000000 ................ 0060 00000000 0201100c 00000010 04000000 ................ 0070 00000000 0202100c 00000010 03200000 ............. .. 0080 00001000 c0011018 00010001 01000000 ................ 0090 00010002 00000000 00010003 01000000 ................ 00a0 0003101c 01000000 00000000 00000200 ................ 00b0 00000000 00000008 00000000 ............ Entering DtaDevOpal::properties() Creating DtaSsession() Creating DtaCommand(ID, InvokingUid, method) Entering DtaCommand::reset(OPAL_UID, OPAL_METHOD) Entering DtaCommand::reset() Entering DtaCommand::addToken(OPAL_UID) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(const char ) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::complete(uint8_t EOD) Entering DtaSession::sendCommand() Entering DtaCommand::setHSN() Entering DtaCommand::setTSN() Entering DtaCommand::setcomID()

Dumping command buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 000000b0 00000000 00000000 00000000 ................ 0020 00000000 00000000 00000098 00000000 ................ 0030 00000000 0000008c f8a80000 00000000 ................ 0040 00ffa800 00000000 00ff01f0 f200f0f2 ................ 0050 d0104d61 78436f6d 5061636b 65745369 ..MaxComPacketSi 0060 7a658208 00f3f2ad 4d617850 61636b65 ze......MaxPacke 0070 7453697a 658207ec f3f2af4d 6178496e tSize......MaxIn 0080 64546f6b 656e5369 7a658207 c8f3f2aa dTokenSize...... 0090 4d617850 61636b65 747301f3 f2ad4d61 MaxPackets....Ma 00a0 78537562 7061636b 65747301 f3f2aa4d xSubpackets....M 00b0 61784d65 74686f64 7301f3f1 f3f1f9f0 axMethods....... 00c0 000000f1 .... Entering DtaDevLinuxSata::sendCmd Entering DtaDevLinuxSata::sendCmd

Dumping reply buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 00000208 00000000 00000000 00000000 ................ 0020 00000000 00000000 000001f0 00000000 ................ 0030 00000000 000001e2 f8a80000 00000000 ................ 0040 00ffa800 00000000 00ff01f0 f0f2aa4d ...............M 0050 61784d65 74686f64 7301f3f2 ad4d6178 axMethods....Max 0060 53756270 61636b65 747301f3 f2ad4d61 Subpackets....Ma 0070 78506163 6b657453 697a6582 43ecf3f2 xPacketSize.C... 0080 aa4d6178 5061636b 65747301 f3f2d010 .MaxPackets..... 0090 4d617843 6f6d5061 636b6574 53697a65 MaxComPacketSize 00a0 824400f3 f2d0184d 61785265 73706f6e .D.....MaxRespon 00b0 7365436f 6d506163 6b657453 697a6582 seComPacketSize. 00c0 4400f3f2 ab4d6178 53657373 696f6e73 D....MaxSessions 00d0 01f3f2af 4d617849 6e64546f 6b656e53 ....MaxIndTokenS 00e0 697a6582 43c8f3f2 d0124d61 78417574 ize.C.....MaxAut 00f0 68656e74 69636174 696f6e73 18f3f2d0 hentications.... 0100 134d6178 5472616e 73616374 696f6e4c .MaxTransactionL 0110 696d6974 01f3f2d0 11446566 53657373 imit.....DefSess 0120 696f6e54 696d656f 757400f3 f2d0114d ionTimeout.....M 0130 61785365 7373696f 6e54696d 656f7574 axSessionTimeout 0140 00f3f2d0 114d696e 53657373 696f6e54 .....MinSessionT 0150 696d656f 757400f3 f2af4465 66547261 imeout....DefTra 0160 6e735469 6d656f75 7400f3f2 af4d6178 nsTimeout....Max 0170 5472616e 7354696d 656f7574 00f3f2af TransTimeout.... 0180 4d696e54 72616e73 54696d65 6f757400 MinTransTimeout. 0190 f3f2ac4d 6178436f 6d494454 696d6500 ...MaxComIDTime. 01a0 f3f1f200 f0f2d010 4d617843 6f6d5061 ........MaxComPa 01b0 636b6574 53697a65 820800f3 f2ad4d61 cketSize......Ma 01c0 78506163 6b657453 697a6582 07ecf3f2 xPacketSize..... 01d0 af4d6178 496e6454 6f6b656e 53697a65 .MaxIndTokenSize 01e0 8207c8f3 f2aa4d61 78506163 6b657473 ......MaxPackets 01f0 01f3f2ad 4d617853 75627061 636b6574 ....MaxSubpacket 0200 7301f3f2 aa4d6178 4d657468 6f647301 s....MaxMethods. 0210 f3f1f3f1 f9f00000 00f10000 ............ Entering DtaResponse::init Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Destroying DtaCommand Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::tokenIs Entering DtaResponse::getString Entering DtaResponse::getString Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Leaving DtaDevOpal::properties() Entering DtaDev::isOpal2 1 Destroying DtaDevOS Destroying DtaDevLinuxSata Destroying DtaResponse Destroying DtaResponse Erasing LockingRange on/dev/sda Entering DtaDevOpal::eraseLockingRange_SUM Creating DtaSsession() Entering DtaSession::startSession Entering DtaSession::startSession Creating DtaCommand() Creating DtaResponse() Entering DtaCommand::reset(OPAL_UID, OPAL_METHOD) Entering DtaCommand::reset() Entering DtaCommand::addToken(OPAL_UID) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(uint64_t) Entering DtaCommand::addToken(OPAL_UID) Entering DtaCommand::addToken(OPAL_TINY_ATOM) Entering DtaDev::isEprise 0 Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TINY_ATOM) Entered DtaHashPwd Entered DtaHashPassword Exit DtaHashPwd Entering addToken(vector) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TINY_ATOM) Entering addToken(vector) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaDev::isEprise 0 Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::complete(uint8_t EOD) Entering DtaSession::sendCommand() Entering DtaCommand::setHSN() Entering DtaCommand::setTSN() Entering DtaCommand::setcomID()

Dumping command buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 0000007c 00000000 00000000 00000000 ...|............ 0020 00000000 00000000 00000064 00000000 ...........d.... 0030 00000000 00000058 f8a80000 00000000 .......X........ 0040 00ffa800 00000000 00ff02f0 8169a800 .............i.. 0050 00020500 00000201 f200d020 6a5089ce ........... jP.. 0060 8017cac4 ecfef5a7 d7f58c90 9af600aa ................ 0070 1cca0c4d bef54abe 72a8a311 f3f203a8 ...M..J.r....... 0080 00000009 00010001 f3f1f9f0 000000f1 ................ Entering DtaDevLinuxSata::sendCmd Entering DtaDevLinuxSata::sendCmd Entering DtaDevLinuxSata::sendCmd

Dumping reply buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 00000048 00000000 00000000 00000000 ...H............ 0020 00000000 00000000 00000030 00000000 ...........0.... 0030 00000000 00000022 f8a80000 00000000 ......."........ 0040 00ffa800 00000000 00ff03f0 816984ff .............i.. 0050 fffc16f1 f9f00000 00f10000 ............ Entering DtaResponse::init Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Entering DtaResponse::getUint32 Entering DtaResponse::getUint64 Destroying DtaCommand Entering DtaDev::isEprise 0 Destroying DtaResponse Creating DtaCommand() Entering DtaCommand::reset(OPAL_UID, OPAL_METHOD) Entering DtaCommand::reset() Entering DtaCommand::addToken(OPAL_UID) Entering DtaCommand::changeInvokingUid() Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::complete(uint8_t EOD) Entering DtaSession::sendCommand() Entering DtaCommand::setHSN() Entering DtaCommand::setTSN() Entering DtaCommand::setcomID()

Dumping command buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 00000040 fffffc16 00000069 00000000 ...@.......i.... 0020 00000000 00000000 00000028 00000000 ...........(.... 0030 00000000 0000001b f8a80000 08020003 ................ 0040 0001a800 00000600 000803f0 f1f9f000 ................ 0050 0000f100 .... Entering DtaDevLinuxSata::sendCmd Entering DtaDevLinuxSata::sendCmd

Dumping reply buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 0000002c fffffc16 00000069 00000000 ...,.......i.... 0020 00000000 00000000 00000014 00000000 ................ 0030 00000000 00000008 f0f1f9f0 010000f1 ................ Entering DtaResponse::init Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::tokenIs Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 Entering DtaSession::methodStatus() method status code NOT_AUTHORIZED Entering DtaResponse::getTokenCount() Entering DtaResponse::getUint8 Entering DtaResponse::getUint64 setLockingRange Failed Destroying DtaCommand Destroying DtaSession Creating DtaResponse() Creating DtaCommand() Entering DtaCommand::reset() Entering DtaCommand::addToken(OPAL_TOKEN) Entering DtaCommand::complete(uint8_t EOD) Entering DtaSession::sendCommand() Entering DtaCommand::setHSN() Entering DtaCommand::setTSN() Entering DtaCommand::setcomID()

Dumping command buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 00000028 fffffc16 00000069 00000000 ...(.......i.... 0020 00000000 00000000 00000010 00000000 ................ 0030 00000000 00000001 fa000000 ............ Entering DtaDevLinuxSata::sendCmd Entering DtaDevLinuxSata::sendCmd

Dumping reply buffer Entering hexDump 0000 00000000 07fe0000 00000000 00000000 ................ 0010 00000028 fffffc16 00000069 00000000 ...(.......i.... 0020 00000000 00000000 00000010 00000000 ................ 0030 00000000 00000001 fa000000 ............ Entering DtaResponse::init Entering DtaResponse::tokenIs Destroying DtaCommand Destroying DtaResponse

r0m30 commented 2 years ago

Did you try rekeylockingrange?

rbmv commented 2 years ago

I'm sorry for the late reply, I had no chance to verify if this worked until now.

RekeyLockingRange did the trick, the command was accepted by the drive, and after rekeying the range and power-cycling, with the range unlocked, the partitions contained become unmountable and original data seems unaccesible, which is what I needed.

Thanks a lot.