Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit e0ca7e6

Browse files
zhouji3xbuildslave
authored andcommitted
[efiwrapper] add NVME security support
this patch support NVME security send/receive and register storage security protocol(SSP) for NVME Change-Id: Iad0b98df5e8554903d8abf7dc5f21cd5d535e091 Tracked-On: https://jira01.devtools.intel.com/browse/OAM-52565 Signed-off-by: JianFeng,Zhou <[email protected]> Reviewed-on: https://android.intel.com:443/657010
1 parent 68778d8 commit e0ca7e6

File tree

8 files changed

+649
-20
lines changed

8 files changed

+649
-20
lines changed

drivers/nvme/NvmCtrlLib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,6 @@ EFI_STATUS EFIAPI NvmeInitialize (IN UINTN NvmeHcPciBase);
147147

148148
EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmeGetPassthru(void);
149149

150+
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *NvmeGetSecurityInterface(void);
151+
150152
#endif

drivers/nvme/NvmExpress.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,25 @@ NvmCtrlPlatformInfo NvmCtrlInfo = { {1,0,0} };
2929

3030
EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmeGetPassthru(void)
3131
{
32-
return (void *)&mNvmeCtrlPrivate->Passthru;
32+
return (void *)&mNvmeCtrlPrivate->Passthru;
3333
}
3434

35+
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *NvmeGetSecurityInterface(void)
36+
{
37+
NVME_DEVICE_PRIVATE_DATA *device = mMultiNvmeDrive[0];
38+
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *security;
39+
40+
if (device == NULL)
41+
return NULL;
42+
43+
security = &device->StorageSecurity;
44+
if (security->SendData == NULL || security->ReceiveData == NULL)
45+
return NULL;
46+
47+
return security;
48+
}
49+
50+
3551
//
3652
// Template for NVM Express Pass Thru Mode data structure.
3753
//
@@ -151,6 +167,17 @@ EnumerateNvmeDevNamespace (
151167
CopyMem (&Device->NamespaceData, NamespaceData, sizeof (NVME_ADMIN_NAMESPACE_DATA));
152168
mMultiNvmeDrive[NamespaceId - 1] = Device; //NamespaceId is 1 based
153169

170+
//
171+
// Create StorageSecurityProtocol Instance
172+
//
173+
Device->StorageSecurity.ReceiveData = NvmeStorageSecurityReceiveData;
174+
Device->StorageSecurity.SendData = NvmeStorageSecuritySendData;
175+
DEBUG_NVME((EFI_D_INFO, "## SECURITY_SEND_RECEIVE %d ####\n", (Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED)));
176+
if ((Private->ControllerData->Oacs & SECURITY_SEND_RECEIVE_SUPPORTED) == 0) {
177+
Device->StorageSecurity.ReceiveData = NULL;
178+
Device->StorageSecurity.SendData = NULL;
179+
}
180+
154181
//
155182
// Dump NvmExpress Identify Namespace Data
156183
//
@@ -392,16 +419,14 @@ NvmeGetMediaInfo (
392419
EFI_STATUS
393420
EFIAPI
394421
NvmeReadBlocks (
395-
IN UINTN DeviceIndex,
422+
IN UINTN DeviceIndex __attribute__((unused)),
396423
IN EFI_PEI_LBA StartLBA,
397424
IN UINTN BufferSize,
398425
OUT VOID *Buffer
399426
)
400427
{
401428
EFI_STATUS Status;
402429

403-
DeviceIndex = DeviceIndex;
404-
405430
Status = NvmeBlockIoReadBlocks(&mMultiNvmeDrive[0]->BlockIo, 0, StartLBA, BufferSize, Buffer);
406431

407432
return Status;
@@ -423,16 +448,14 @@ NvmeReadBlocks (
423448
EFI_STATUS
424449
EFIAPI
425450
NvmeWriteBlocks (
426-
IN UINTN DeviceIndex,
451+
IN UINTN DeviceIndex __attribute__((unused)),
427452
IN EFI_LBA StartLBA,
428453
IN UINTN DataSize,
429454
IN VOID *DataAddress
430455
)
431456
{
432457
EFI_STATUS Status;
433458

434-
DeviceIndex = DeviceIndex;
435-
436459
Status = NvmeBlockIoWriteBlocks(&mMultiNvmeDrive[0]->BlockIo, 0, StartLBA, DataSize, DataAddress);
437460

438461
return Status;

drivers/nvme/NvmExpress.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <external.h>
2323

2424
#include "NvmInternal.h"
25+
#include "protocol/StorageSecurityCommand.h"
2526

2627
#define nvme_dbg(a, ...) { printf(__VA_ARGS__); }
2728
#define DEBUG_NVME(a) (nvme_dbg a)
@@ -219,6 +220,7 @@ struct _NVME_DEVICE_PRIVATE_DATA {
219220

220221
NVME_CONTROLLER_PRIVATE_DATA *Controller;
221222

223+
EFI_STORAGE_SECURITY_COMMAND_PROTOCOL StorageSecurity;
222224
};
223225

224226
//

drivers/nvme/NvmExpressBlockIo.c

Lines changed: 221 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,15 +337,13 @@ EFI_STATUS
337337
EFIAPI
338338
NvmeBlockIoReset (
339339
IN EFI_BLOCK_IO_PROTOCOL *This,
340-
IN BOOLEAN ExtendedVerification
340+
IN BOOLEAN ExtendedVerification __attribute__((unused))
341341
)
342342
{
343343
NVME_CONTROLLER_PRIVATE_DATA *Private;
344344
NVME_DEVICE_PRIVATE_DATA *Device;
345345
EFI_STATUS Status;
346346

347-
ExtendedVerification = ExtendedVerification;
348-
349347
if (This == NULL) {
350348
return EFI_INVALID_PARAMETER;
351349
}
@@ -584,7 +582,6 @@ TrustTransferNvmeDevice (
584582
EFI_NVM_EXPRESS_COMMAND Command;
585583
EFI_NVM_EXPRESS_COMPLETION Completion;
586584
EFI_STATUS Status;
587-
UINT16 SpecificData;
588585

589586
ZeroMem (&CommandPacket, sizeof (EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET));
590587
ZeroMem (&Command, sizeof (EFI_NVM_EXPRESS_COMMAND));
@@ -593,22 +590,17 @@ TrustTransferNvmeDevice (
593590
CommandPacket.NvmeCmd = &Command;
594591
CommandPacket.NvmeCompletion = &Completion;
595592

596-
//
597-
// Change Endianness of SecurityProtocolSpecificData
598-
//
599-
SpecificData = (((SecurityProtocolSpecificData << 8) & 0xFF00) | (SecurityProtocolSpecificData >> 8));
600-
601593
if (IsTrustSend) {
602594
Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_SEND_CMD;
603595
CommandPacket.TransferBuffer = Buffer;
604596
CommandPacket.TransferLength = (UINT32)TransferLength;
605-
CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));
597+
CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SecurityProtocolSpecificData << 8));
606598
CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
607599
} else {
608600
Command.Cdw0.Opcode = NVME_ADMIN_SECURITY_RECEIVE_CMD;
609601
CommandPacket.TransferBuffer = Buffer;
610602
CommandPacket.TransferLength = (UINT32)TransferLength;
611-
CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SpecificData << 8));
603+
CommandPacket.NvmeCmd->Cdw10 = (UINT32)((SecurityProtocolId << 24) | (SecurityProtocolSpecificData << 8));
612604
CommandPacket.NvmeCmd->Cdw11 = (UINT32)TransferLength;
613605
}
614606

@@ -635,3 +627,221 @@ TrustTransferNvmeDevice (
635627
return Status;
636628
}
637629

630+
/**
631+
Send a security protocol command to a device that receives data and/or the result
632+
of one or more commands sent by SendData.
633+
634+
The ReceiveData function sends a security protocol command to the given MediaId.
635+
The security protocol command sent is defined by SecurityProtocolId and contains
636+
the security protocol specific data SecurityProtocolSpecificData. The function
637+
returns the data from the security protocol command in PayloadBuffer.
638+
639+
For devices supporting the SCSI command set, the security protocol command is sent
640+
using the SECURITY PROTOCOL IN command defined in SPC-4.
641+
642+
For devices supporting the ATA command set, the security protocol command is sent
643+
using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize
644+
is non-zero.
645+
646+
If the PayloadBufferSize is zero, the security protocol command is sent using the
647+
Trusted Non-Data command defined in ATA8-ACS.
648+
649+
If PayloadBufferSize is too small to store the available data from the security
650+
protocol command, the function shall copy PayloadBufferSize bytes into the
651+
PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.
652+
653+
If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,
654+
the function shall return EFI_INVALID_PARAMETER.
655+
656+
If the given MediaId does not support security protocol commands, the function shall
657+
return EFI_UNSUPPORTED. If there is no media in the device, the function returns
658+
EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,
659+
the function returns EFI_MEDIA_CHANGED.
660+
661+
If the security protocol fails to complete within the Timeout period, the function
662+
shall return EFI_TIMEOUT.
663+
664+
If the security protocol command completes without an error, the function shall
665+
return EFI_SUCCESS. If the security protocol command completes with an error, the
666+
function shall return EFI_DEVICE_ERROR.
667+
668+
@param This Indicates a pointer to the calling context.
669+
@param MediaId ID of the medium to receive data from.
670+
@param Timeout The timeout, in 100ns units, to use for the execution
671+
of the security protocol command. A Timeout value of 0
672+
means that this function will wait indefinitely for the
673+
security protocol command to execute. If Timeout is greater
674+
than zero, then this function will return EFI_TIMEOUT
675+
if the time required to execute the receive data command
676+
is greater than Timeout.
677+
@param SecurityProtocolId The value of the "Security Protocol" parameter of
678+
the security protocol command to be sent.
679+
@param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
680+
of the security protocol command to be sent.
681+
@param PayloadBufferSize Size in bytes of the payload data buffer.
682+
@param PayloadBuffer A pointer to a destination buffer to store the security
683+
protocol command specific payload data for the security
684+
protocol command. The caller is responsible for having
685+
either implicit or explicit ownership of the buffer.
686+
@param PayloadTransferSize A pointer to a buffer to store the size in bytes of the
687+
data written to the payload data buffer.
688+
689+
@retval EFI_SUCCESS The security protocol command completed successfully.
690+
@retval EFI_WARN_BUFFER_TOO_SMALL The PayloadBufferSize was too small to store the available
691+
data from the device. The PayloadBuffer contains the truncated data.
692+
@retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
693+
@retval EFI_DEVICE_ERROR The security protocol command completed with an error.
694+
@retval EFI_NO_MEDIA There is no media in the device.
695+
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
696+
@retval EFI_INVALID_PARAMETER The PayloadBuffer or PayloadTransferSize is NULL and
697+
PayloadBufferSize is non-zero.
698+
@retval EFI_TIMEOUT A timeout occurred while waiting for the security
699+
protocol command to execute.
700+
701+
**/
702+
EFI_STATUS
703+
EFIAPI
704+
NvmeStorageSecurityReceiveData (
705+
IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
706+
IN UINT32 MediaId,
707+
IN UINT64 Timeout,
708+
IN UINT8 SecurityProtocolId,
709+
IN UINT16 SecurityProtocolSpecificData,
710+
IN UINTN PayloadBufferSize,
711+
OUT VOID *PayloadBuffer,
712+
OUT UINTN *PayloadTransferSize
713+
)
714+
{
715+
EFI_STATUS Status;
716+
NVME_DEVICE_PRIVATE_DATA *Device;
717+
718+
Status = EFI_SUCCESS;
719+
720+
if ((PayloadBuffer == NULL) || (PayloadTransferSize == NULL) || (PayloadBufferSize == 0))
721+
return EFI_INVALID_PARAMETER;
722+
723+
Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(This);
724+
725+
if (MediaId != Device->BlockIo.Media->MediaId)
726+
return EFI_MEDIA_CHANGED;
727+
728+
if (!Device->BlockIo.Media->MediaPresent)
729+
return EFI_NO_MEDIA;
730+
731+
Status = TrustTransferNvmeDevice(
732+
Device->Controller,
733+
PayloadBuffer,
734+
SecurityProtocolId,
735+
SecurityProtocolSpecificData,
736+
PayloadBufferSize,
737+
FALSE,
738+
Timeout,
739+
PayloadTransferSize
740+
);
741+
742+
return Status;
743+
}
744+
745+
/**
746+
Send a security protocol command to a device.
747+
748+
The SendData function sends a security protocol command containing the payload
749+
PayloadBuffer to the given MediaId. The security protocol command sent is
750+
defined by SecurityProtocolId and contains the security protocol specific data
751+
SecurityProtocolSpecificData. If the underlying protocol command requires a
752+
specific padding for the command payload, the SendData function shall add padding
753+
bytes to the command payload to satisfy the padding requirements.
754+
755+
For devices supporting the SCSI command set, the security protocol command is sent
756+
using the SECURITY PROTOCOL OUT command defined in SPC-4.
757+
758+
For devices supporting the ATA command set, the security protocol command is sent
759+
using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize
760+
is non-zero. If the PayloadBufferSize is zero, the security protocol command is
761+
sent using the Trusted Non-Data command defined in ATA8-ACS.
762+
763+
If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall
764+
return EFI_INVALID_PARAMETER.
765+
766+
If the given MediaId does not support security protocol commands, the function
767+
shall return EFI_UNSUPPORTED. If there is no media in the device, the function
768+
returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the
769+
device, the function returns EFI_MEDIA_CHANGED.
770+
771+
If the security protocol fails to complete within the Timeout period, the function
772+
shall return EFI_TIMEOUT.
773+
774+
If the security protocol command completes without an error, the function shall return
775+
EFI_SUCCESS. If the security protocol command completes with an error, the function
776+
shall return EFI_DEVICE_ERROR.
777+
778+
@param This Indicates a pointer to the calling context.
779+
@param MediaId ID of the medium to receive data from.
780+
@param Timeout The timeout, in 100ns units, to use for the execution
781+
of the security protocol command. A Timeout value of 0
782+
means that this function will wait indefinitely for the
783+
security protocol command to execute. If Timeout is greater
784+
than zero, then this function will return EFI_TIMEOUT
785+
if the time required to execute the send data command
786+
is greater than Timeout.
787+
@param SecurityProtocolId The value of the "Security Protocol" parameter of
788+
the security protocol command to be sent.
789+
@param SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
790+
of the security protocol command to be sent.
791+
@param PayloadBufferSize Size in bytes of the payload data buffer.
792+
@param PayloadBuffer A pointer to a destination buffer to store the security
793+
protocol command specific payload data for the security
794+
protocol command.
795+
796+
@retval EFI_SUCCESS The security protocol command completed successfully.
797+
@retval EFI_UNSUPPORTED The given MediaId does not support security protocol commands.
798+
@retval EFI_DEVICE_ERROR The security protocol command completed with an error.
799+
@retval EFI_NO_MEDIA There is no media in the device.
800+
@retval EFI_MEDIA_CHANGED The MediaId is not for the current media.
801+
@retval EFI_INVALID_PARAMETER The PayloadBuffer is NULL and PayloadBufferSize is non-zero.
802+
@retval EFI_TIMEOUT A timeout occurred while waiting for the security
803+
protocol command to execute.
804+
805+
**/
806+
EFI_STATUS
807+
EFIAPI
808+
NvmeStorageSecuritySendData(
809+
IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
810+
IN UINT32 MediaId,
811+
IN UINT64 Timeout,
812+
IN UINT8 SecurityProtocolId,
813+
IN UINT16 SecurityProtocolSpecificData,
814+
IN UINTN PayloadBufferSize,
815+
IN VOID *PayloadBuffer
816+
)
817+
{
818+
EFI_STATUS Status;
819+
NVME_DEVICE_PRIVATE_DATA *Device;
820+
821+
Status = EFI_SUCCESS;
822+
823+
if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0))
824+
return EFI_INVALID_PARAMETER;
825+
826+
Device = NVME_DEVICE_PRIVATE_DATA_FROM_STORAGE_SECURITY(This);
827+
828+
if (MediaId != Device->BlockIo.Media->MediaId)
829+
return EFI_MEDIA_CHANGED;
830+
831+
if (!Device->BlockIo.Media->MediaPresent)
832+
return EFI_NO_MEDIA;
833+
834+
Status = TrustTransferNvmeDevice(
835+
Device->Controller,
836+
PayloadBuffer,
837+
SecurityProtocolId,
838+
SecurityProtocolSpecificData,
839+
PayloadBufferSize,
840+
TRUE,
841+
Timeout,
842+
NULL
843+
);
844+
845+
return Status;
846+
}
847+

0 commit comments

Comments
 (0)