--- /dev/null
+nvme-help(1)
+=============
+
+NAME
+----
+nvme-security-recv - Security Recv command
+
+SYNOPSIS
+--------
+[verse]
+'nvme security-recv' [<device>] [--size=<size> | -x <size>]
+ [--secp=<security-protocol> | -p <security-protocol>]
+ [--spsp=<protocol-specific> | -s <protocol-specific>]
+ [--tl=<transfer-length> | -t <transfer-length>]
+ [-b | --raw-binary]
+
+DESCRIPTION
+-----------
+The Security Receive command transfers the status and data result of
+one or more Security Send commands that were previously submitted to
+the controller.
+
+The association between a Security Receive command and previous Security
+Send commands is dependent on the Security Protocol. The format of the
+data to be transferred is dependent on the Security Protocol. Refer to
+SPC-4 for Security Protocol details.
+
+Each Security Receive command returns the appropriate data corresponding
+to a Security Send command as defined by the rules of the Security
+Protocol. The Security Receive command data may not be retained if there
+is a loss of communication between the controller and host, or if a
+controller reset occurs.
+
+OPTIONS
+-------
+-x <size>::
+--size=<size>::
+ Size of buffer to allocate. One success it will be printed
+ to STDOUT.
+
+-p <security-protocol>::
+--secp=<security-protocol>::
+ Security Protocol: This field specifies the security protocol
+ as defined in SPC-4. The controller shall fail the command with
+ Invalid Parameter indicated if a reserved value of the Security
+ Protocol is specified.
+
+-s <security-protocol-specific>::
+--spsp=<security-protocol-specific>::
+ SP Specific: The value of this field is specific to the Security
+ Protocol as defined in SPC-4.
+
+-a <allocation-length>::
+--al=<allocation-length>::
+ Allocation Length: The value of this field is specific to the
+ Security Protocol as defined in SPC-4.
+
+-b::
+--raw-binary::
+ Print the raw buffer to stdout. Defaults to print in hex.
+
+EXAMPLES
+--------
+No Examples
+
+NVME
+----
+Part of the nvme-user suite
--- /dev/null
+nvme-help(1)
+=============
+
+NAME
+----
+nvme-security-send - Security Send command
+
+SYNOPSIS
+--------
+[verse]
+'nvme security-send' [<device>] [--file=<file> | -f <file>]
+ [--secp=<security-protocol> | -p <security-protocol>]
+ [--spsp=<protocol-specific> | -s <protocol-specific>]
+ [--tl=<transfer-length> | -t <transfer-length>]
+
+DESCRIPTION
+-----------
+The Security Send command is used to transfer security protocol data
+to the controller. The data structure transferred to the controller
+as part of this command contains security protocol specific commands
+to be performed by the controller. The data structure transferred may
+also contain data or parameters associated with the security protocol
+commands. Status and data that is to be returned to the host for the
+security protocol commands submitted by a Security Send command are
+retrieved with the Security Receive command.
+
+The association between a Security Send command and subsequent Security
+Receive command is Security Protocol field dependent as defined in SPC-4.
+
+OPTIONS
+-------
+-f <file>::
+--file=<file>::
+ Path to file used as the security protocol's payload. Required
+ argument.
+
+-p <security-protocol>::
+--secp=<security-protocol>::
+ Security Protocol: This field specifies the security protocol
+ as defined in SPC-4. The controller shall fail the command with
+ Invalid Parameter indicated if a reserved value of the Security
+ Protocol is specified.
+
+-s <security-protocol-specific>::
+--spsp=<security-protocol-specific>::
+ SP Specific: The value of this field is specific to the Security
+ Protocol as defined in SPC-4.
+
+-t <trans-length>::
+--tl=<trans-length>::
+ Transfer Length: The value of this field is specific to the
+ Security Protocol as defined in SPC-4.
+
+EXAMPLES
+--------
+No Examples
+
+NVME
+----
+Part of the nvme-user suite
ENTRY(FW_DOWNLOAD, "fw-download", "Download new firmware", fw_download) \
ENTRY(ADMIN_PASSTHRU, "admin-passthru", "Submit arbitrary admin command, return results", admin_passthru) \
ENTRY(IO_PASSTHRU, "io-passthru", "Submit an arbitrary IO command, return results", io_passthru) \
+ ENTRY(SECURITY_SEND, "security-send", "Submit a Security Send command, return results", sec_send) \
+ ENTRY(SECURITY_RECV, "security-recv", "Submit a Security Receive command, return results", sec_recv) \
ENTRY(HELP, "help", "Display this help", help)
#define ENTRY(i, n, h, f) \
if (fw_fd < 0) {
fprintf(stderr, "no firmware file provided\n");
- exit(EINVAL);
+ return EINVAL;
}
err = fstat(fw_fd, &sb);
if (err < 0) {
return err;
}
+static int sec_send(int argc, char **argv)
+{
+ struct stat sb;
+ struct nvme_admin_cmd cmd;
+ int err, sec_fd = -1, opt, long_index = 0;
+ void *sec_buf;
+ unsigned int tl = 0;
+ unsigned short spsp = 0;
+ unsigned char secp = 0;
+ unsigned int sec_size;
+ static struct option opts[] = {
+ {"file", required_argument, 0, 'f'},
+ {"secp", required_argument, 0, 'p'},
+ {"spsp", required_argument, 0, 's'},
+ {"tl", required_argument, 0, 't'},
+ { 0, 0, 0, 0}
+ };
+
+ while ((opt = getopt_long(argc, (char **)argv, "f:p:s:t:", opts,
+ &long_index)) != -1) {
+ switch(opt) {
+ case 'f':
+ sec_fd = open(optarg, O_RDONLY);
+ break;
+ case 'p':
+ get_short(optarg, &spsp);
+ break;
+ case 's':
+ get_byte(optarg, &secp);
+ break;
+ case 't':
+ get_int(optarg, &tl);
+ break;
+ default:
+ return EINVAL;
+ }
+ }
+ get_dev(optind, argc, argv);
+
+ if (sec_fd < 0) {
+ fprintf(stderr, "no firmware file provided\n");
+ return EINVAL;
+ }
+ err = fstat(sec_fd, &sb);
+ if (err < 0) {
+ perror("fstat");
+ return errno;
+ }
+ sec_size = sb.st_size;
+ if (posix_memalign(&sec_buf, getpagesize(), sec_size)) {
+ fprintf(stderr, "No memory for security size:%d\n", sec_size);
+ return ENOMEM;
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opcode = nvme_admin_security_send;
+ cmd.cdw10 = secp << 24 | spsp << 8;
+ cmd.cdw11 = tl;
+ cmd.data_len = sec_size;
+ cmd.addr = (__u64)sec_buf;
+
+ err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd);
+ if (err < 0)
+ return errno;
+ else if (err != 0)
+ fprintf(stderr, "NVME Security Send Command Error:%d\n", err);
+ else
+ printf("NVME Security Send Command Success:%d\n", cmd.result);
+ return err;
+}
+
+static int sec_recv(int argc, char **argv)
+{
+ struct nvme_admin_cmd cmd;
+ int err, opt, long_index = 0, raw = 0;
+ void *sec_buf = NULL;
+ unsigned int al = 0;
+ unsigned short spsp = 0;
+ unsigned char secp = 0;
+ unsigned int sec_size = 0;
+ static struct option opts[] = {
+ {"size", required_argument, 0, 'x'},
+ {"file", required_argument, 0, 'f'},
+ {"secp", required_argument, 0, 'p'},
+ {"spsp", required_argument, 0, 's'},
+ {"al", required_argument, 0, 't'},
+ {"raw-binary", no_argument, 0, 'b'},
+ { 0, 0, 0, 0}
+ };
+
+ while ((opt = getopt_long(argc, (char **)argv, "f:p:s:t:", opts,
+ &long_index)) != -1) {
+ switch(opt) {
+ case 'x':
+ get_int(optarg, &sec_size);
+ break;
+ case 'p':
+ get_short(optarg, &spsp);
+ break;
+ case 's':
+ get_byte(optarg, &secp);
+ break;
+ case 't':
+ get_int(optarg, &al);
+ break;
+ case 'b':
+ raw = 1;
+ break;
+ default:
+ return EINVAL;
+ }
+ }
+ get_dev(optind, argc, argv);
+
+ if (sec_size) {
+ if (posix_memalign(&sec_buf, getpagesize(), sec_size)) {
+ fprintf(stderr, "No memory for security size:%d\n",
+ sec_size);
+ return ENOMEM;
+ }
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opcode = nvme_admin_security_recv;
+ cmd.cdw10 = secp << 24 | spsp << 8;
+ cmd.cdw11 = al;
+ cmd.data_len = sec_size;
+ cmd.addr = (__u64)sec_buf;
+
+ err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd);
+ if (err < 0)
+ return errno;
+ else if (err != 0)
+ fprintf(stderr, "NVME Security Receivce Command Error:%d\n",
+ err);
+ else {
+ if (!raw) {
+ printf("NVME Security Receivce Command Success:%d\n",
+ cmd.result);
+ d(sec_buf, sec_size, 16, 1);
+ } else if (sec_size)
+ d_raw((unsigned char *)&sec_buf, sec_size);
+ }
+ return err;
+}
+
static int io_passthru(int argc, char **argv)
{
fprintf(stderr, "%s: not implemented yet\n", __func__);