Merging upstream version 2.11.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
6f6d3e85f8
commit
0f2367f2fa
533 changed files with 9033 additions and 4835 deletions
262
nvme.c
262
nvme.c
|
@ -76,10 +76,11 @@ struct feat_cfg {
|
|||
enum nvme_get_features_sel sel;
|
||||
__u32 cdw11;
|
||||
__u32 cdw12;
|
||||
__u8 uuid_index;
|
||||
__u8 uuid_index;
|
||||
__u32 data_len;
|
||||
bool raw_binary;
|
||||
bool human_readable;
|
||||
bool raw_binary;
|
||||
bool human_readable;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
struct passthru_config {
|
||||
|
@ -1168,7 +1169,7 @@ static int get_error_log(int argc, char **argv, struct command *cmd, struct plug
|
|||
|
||||
_cleanup_free_ struct nvme_error_log_page *err_log = NULL;
|
||||
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
|
||||
struct nvme_id_ctrl ctrl;
|
||||
struct nvme_id_ctrl ctrl = { 0 };
|
||||
nvme_print_flags_t flags;
|
||||
int err = -1;
|
||||
|
||||
|
@ -2965,7 +2966,7 @@ static int parse_lba_num_si(struct nvme_dev *dev, const char *opt,
|
|||
}
|
||||
|
||||
nvme_id_ns_flbas_to_lbaf_inuse(flbas, &lbaf);
|
||||
lbas = (1 << ns->lbaf[lbaf].ds) + ns->lbaf[lbaf].ms;
|
||||
lbas = (1 << ns->lbaf[lbaf].ds) + le16_to_cpu(ns->lbaf[lbaf].ms);
|
||||
|
||||
if (suffix_si_parse(val, &endptr, (uint64_t *)num)) {
|
||||
nvme_show_error("Expected long suffixed integer argument for '%s-si' but got '%s'!",
|
||||
|
@ -3467,6 +3468,9 @@ static int nvm_id_ctrl(int argc, char **argv, struct command *cmd,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (argconfig_parse_seen(opts, "verbose"))
|
||||
flags |= VERBOSE;
|
||||
|
||||
ctrl_nvm = nvme_alloc(sizeof(*ctrl_nvm));
|
||||
if (!ctrl_nvm)
|
||||
return -ENOMEM;
|
||||
|
@ -4550,7 +4554,7 @@ static int get_feature_id(struct nvme_dev *dev, struct feat_cfg *cfg,
|
|||
cfg->cdw11 |= 0xff << 16;
|
||||
}
|
||||
|
||||
if (cfg->sel == 3)
|
||||
if (NVME_CHECK(cfg->sel, GET_FEATURES_SEL, SUPPORTED))
|
||||
cfg->data_len = 0;
|
||||
|
||||
if (cfg->data_len) {
|
||||
|
@ -4580,8 +4584,7 @@ static int filter_out_flags(int status)
|
|||
NVME_GET(NVME_SC_MASK, SC));
|
||||
}
|
||||
|
||||
static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
|
||||
void *buf)
|
||||
static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result, void *buf)
|
||||
{
|
||||
int status = filter_out_flags(err);
|
||||
enum nvme_status_type type = NVME_STATUS_TYPE_NVME;
|
||||
|
@ -4589,11 +4592,10 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
|
|||
if (!err) {
|
||||
if (!cfg.raw_binary || !buf) {
|
||||
nvme_feature_show(cfg.feature_id, cfg.sel, result);
|
||||
if (cfg.sel == 3)
|
||||
if (NVME_CHECK(cfg.sel, GET_FEATURES_SEL, SUPPORTED))
|
||||
nvme_show_select_result(cfg.feature_id, result);
|
||||
else if (cfg.human_readable)
|
||||
nvme_feature_show_fields(cfg.feature_id, result,
|
||||
buf);
|
||||
nvme_feature_show_fields(cfg.feature_id, result, buf);
|
||||
else if (buf)
|
||||
d(buf, cfg.data_len, 16, 1);
|
||||
} else if (buf) {
|
||||
|
@ -4601,15 +4603,14 @@ static void get_feature_id_print(struct feat_cfg cfg, int err, __u32 result,
|
|||
}
|
||||
} else if (err > 0) {
|
||||
if (!nvme_status_equals(status, type, NVME_SC_INVALID_FIELD) &&
|
||||
!nvme_status_equals(status, type, NVME_SC_INVALID_NS))
|
||||
!nvme_status_equals(status, type, NVME_SC_INVALID_NS))
|
||||
nvme_show_status(err);
|
||||
} else {
|
||||
nvme_show_error("get-feature: %s", nvme_strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
|
||||
bool changed)
|
||||
static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg)
|
||||
{
|
||||
int err;
|
||||
int err_def = 0;
|
||||
|
@ -4618,20 +4619,17 @@ static int get_feature_id_changed(struct nvme_dev *dev, struct feat_cfg cfg,
|
|||
_cleanup_free_ void *buf = NULL;
|
||||
_cleanup_free_ void *buf_def = NULL;
|
||||
|
||||
if (changed)
|
||||
cfg.sel = 0;
|
||||
if (cfg.changed)
|
||||
cfg.sel = NVME_GET_FEATURES_SEL_CURRENT;
|
||||
|
||||
err = get_feature_id(dev, &cfg, &buf, &result);
|
||||
|
||||
if (!err && changed) {
|
||||
cfg.sel = 1;
|
||||
if (!err && cfg.changed) {
|
||||
cfg.sel = NVME_GET_FEATURES_SEL_DEFAULT;
|
||||
err_def = get_feature_id(dev, &cfg, &buf_def, &result_def);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
cfg.sel = 8;
|
||||
|
||||
if (err || !changed || err_def || result != result_def ||
|
||||
if (err || !cfg.changed || err_def || result != result_def ||
|
||||
(buf && buf_def && !strcmp(buf, buf_def)))
|
||||
get_feature_id_print(cfg, err, result, buf);
|
||||
|
||||
|
@ -4644,19 +4642,15 @@ static int get_feature_ids(struct nvme_dev *dev, struct feat_cfg cfg)
|
|||
int i;
|
||||
int feat_max = 0x100;
|
||||
int feat_num = 0;
|
||||
bool changed = false;
|
||||
int status = 0;
|
||||
enum nvme_status_type type = NVME_STATUS_TYPE_NVME;
|
||||
|
||||
if (cfg.sel == 8)
|
||||
changed = true;
|
||||
|
||||
if (cfg.feature_id)
|
||||
feat_max = cfg.feature_id + 1;
|
||||
|
||||
for (i = cfg.feature_id; i < feat_max; i++, feat_num++) {
|
||||
cfg.feature_id = i;
|
||||
err = get_feature_id_changed(dev, cfg, changed);
|
||||
err = get_feature_id_changed(dev, cfg);
|
||||
if (!err)
|
||||
continue;
|
||||
status = filter_out_flags(err);
|
||||
|
@ -4688,9 +4682,10 @@ static int get_feature(int argc, char **argv, struct command *cmd,
|
|||
"change saveable Features.";
|
||||
const char *raw = "show feature in binary format";
|
||||
const char *feature_id = "feature identifier";
|
||||
const char *sel = "[0-3,8]: current/default/saved/supported/changed";
|
||||
const char *sel = "[0-3]: current/default/saved/supported";
|
||||
const char *cdw11 = "feature specific dword 11";
|
||||
const char *human_readable = "show feature in readable format";
|
||||
const char *changed = "show feature changed";
|
||||
|
||||
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
|
||||
int err;
|
||||
|
@ -4698,7 +4693,7 @@ static int get_feature(int argc, char **argv, struct command *cmd,
|
|||
struct feat_cfg cfg = {
|
||||
.feature_id = 0,
|
||||
.namespace_id = 0,
|
||||
.sel = 0,
|
||||
.sel = NVME_GET_FEATURES_SEL_CURRENT,
|
||||
.data_len = 0,
|
||||
.raw_binary = false,
|
||||
.cdw11 = 0,
|
||||
|
@ -4714,7 +4709,8 @@ static int get_feature(int argc, char **argv, struct command *cmd,
|
|||
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
|
||||
OPT_UINT("cdw11", 'c', &cfg.cdw11, cdw11),
|
||||
OPT_BYTE("uuid-index", 'U', &cfg.uuid_index, uuid_index_specify),
|
||||
OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable));
|
||||
OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
|
||||
OPT_FLAG("changed", 'C', &cfg.changed, changed));
|
||||
|
||||
err = parse_and_open(&dev, argc, argv, desc, opts);
|
||||
if (err)
|
||||
|
@ -4731,7 +4727,7 @@ static int get_feature(int argc, char **argv, struct command *cmd,
|
|||
}
|
||||
}
|
||||
|
||||
if (cfg.sel > 8) {
|
||||
if (cfg.sel > NVME_GET_FEATURES_SEL_SUPPORTED) {
|
||||
nvme_show_error("invalid 'select' param:%d", cfg.sel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -5177,11 +5173,13 @@ static int ns_rescan(int argc, char **argv, struct command *cmd, struct plugin *
|
|||
static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Send a sanitize command.";
|
||||
const char *emvs_desc = "Enter media verification state.";
|
||||
const char *no_dealloc_desc = "No deallocate after sanitize.";
|
||||
const char *oipbp_desc = "Overwrite invert pattern between passes.";
|
||||
const char *owpass_desc = "Overwrite pass count.";
|
||||
const char *ause_desc = "Allow unrestricted sanitize exit.";
|
||||
const char *sanact_desc = "Sanitize action: 1 = Exit failure mode, 2 = Start block erase, 3 = Start overwrite, 4 = Start crypto erase";
|
||||
const char *sanact_desc = "Sanitize action: 1 = Exit failure mode, 2 = Start block erase,"
|
||||
"3 = Start overwrite, 4 = Start crypto erase, 5 = Exit media verification";
|
||||
const char *ovrpat_desc = "Overwrite pattern.";
|
||||
|
||||
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
|
||||
|
@ -5194,6 +5192,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
bool ause;
|
||||
__u8 sanact;
|
||||
__u32 ovrpat;
|
||||
bool emvs;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
|
@ -5203,6 +5202,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
.ause = false,
|
||||
.sanact = 0,
|
||||
.ovrpat = 0,
|
||||
.emvs = false,
|
||||
};
|
||||
|
||||
OPT_VALS(sanact) = {
|
||||
|
@ -5210,6 +5210,7 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
VAL_BYTE("start-block-erase", NVME_SANITIZE_SANACT_START_BLOCK_ERASE),
|
||||
VAL_BYTE("start-overwrite", NVME_SANITIZE_SANACT_START_OVERWRITE),
|
||||
VAL_BYTE("start-crypto-erase", NVME_SANITIZE_SANACT_START_CRYPTO_ERASE),
|
||||
VAL_BYTE("exit-media-verification", NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF),
|
||||
VAL_END()
|
||||
};
|
||||
|
||||
|
@ -5219,7 +5220,8 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
OPT_BYTE("owpass", 'n', &cfg.owpass, owpass_desc),
|
||||
OPT_FLAG("ause", 'u', &cfg.ause, ause_desc),
|
||||
OPT_BYTE("sanact", 'a', &cfg.sanact, sanact_desc, sanact),
|
||||
OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc));
|
||||
OPT_UINT("ovrpat", 'p', &cfg.ovrpat, ovrpat_desc),
|
||||
OPT_FLAG("emvs", 'e', &cfg.emvs, emvs_desc));
|
||||
|
||||
err = parse_and_open(&dev, argc, argv, desc, opts);
|
||||
if (err)
|
||||
|
@ -5230,16 +5232,20 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
case NVME_SANITIZE_SANACT_START_BLOCK_ERASE:
|
||||
case NVME_SANITIZE_SANACT_START_OVERWRITE:
|
||||
case NVME_SANITIZE_SANACT_START_CRYPTO_ERASE:
|
||||
case NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF:
|
||||
break;
|
||||
default:
|
||||
nvme_show_error("Invalid Sanitize Action");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
|
||||
if (cfg.ause || cfg.no_dealloc) {
|
||||
if (cfg.ause || cfg.no_dealloc) {
|
||||
if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_FAILURE) {
|
||||
nvme_show_error("SANACT is Exit Failure Mode");
|
||||
return -EINVAL;
|
||||
} else if (cfg.sanact == NVME_SANITIZE_SANACT_EXIT_MEDIA_VERIF) {
|
||||
nvme_show_error("SANACT is Exit Media Verification State");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5264,7 +5270,9 @@ static int sanitize_cmd(int argc, char **argv, struct command *cmd, struct plugi
|
|||
.nodas = cfg.no_dealloc,
|
||||
.ovrpat = cfg.ovrpat,
|
||||
.result = NULL,
|
||||
.emvs = cfg.emvs,
|
||||
};
|
||||
|
||||
err = nvme_cli_sanitize_nvm(dev, &args);
|
||||
if (err < 0)
|
||||
nvme_show_error("sanitize: %s", nvme_strerror(errno));
|
||||
|
@ -5289,6 +5297,11 @@ static int nvme_get_single_property(int fd, struct get_reg_config *cfg, __u64 *v
|
|||
if (!err)
|
||||
return 0;
|
||||
|
||||
if (cfg->fabrics && nvme_is_fabrics_optional_reg(cfg->offset)) {
|
||||
*value = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cfg->fabrics &&
|
||||
nvme_status_equals(err, NVME_STATUS_TYPE_NVME, NVME_SC_INVALID_FIELD)) {
|
||||
*value = -1;
|
||||
|
@ -5320,6 +5333,9 @@ static int nvme_get_properties(int fd, void **pbar, struct get_reg_config *cfg)
|
|||
memset(bar, 0xff, size);
|
||||
for (offset = NVME_REG_CAP; offset <= NVME_REG_CMBSZ;
|
||||
offset += is_64bit ? sizeof(uint64_t) : sizeof(uint32_t)) {
|
||||
if (!nvme_is_fabrics_reg(offset))
|
||||
continue;
|
||||
|
||||
cfg->offset = offset;
|
||||
err = nvme_get_single_property(fd, cfg, &value);
|
||||
if (err)
|
||||
|
@ -5384,12 +5400,12 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
|
|||
|
||||
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
|
||||
nvme_print_flags_t flags;
|
||||
bool fabrics = false;
|
||||
void *bar;
|
||||
int err;
|
||||
|
||||
struct get_reg_config cfg = {
|
||||
.human_readable = false,
|
||||
.fabrics = false,
|
||||
};
|
||||
|
||||
NVME_ARGS(opts,
|
||||
|
@ -5410,14 +5426,14 @@ static int show_registers(int argc, char **argv, struct command *cmd, struct plu
|
|||
|
||||
bar = mmap_registers(dev, false);
|
||||
if (!bar) {
|
||||
cfg.fabrics = true;
|
||||
err = nvme_get_properties(dev_fd(dev), &bar, &cfg);
|
||||
if (err)
|
||||
return err;
|
||||
fabrics = true;
|
||||
}
|
||||
|
||||
nvme_show_ctrl_registers(bar, fabrics, flags);
|
||||
if (fabrics)
|
||||
nvme_show_ctrl_registers(bar, cfg.fabrics, flags);
|
||||
if (cfg.fabrics)
|
||||
free(bar);
|
||||
else
|
||||
munmap(bar, getpagesize());
|
||||
|
@ -6166,7 +6182,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
|
|||
return -errno;
|
||||
}
|
||||
|
||||
if ((ctrl->fna & 1) == 1) {
|
||||
if (ctrl->fna & NVME_CTRL_FNA_FMT_ALL_NAMESPACES) {
|
||||
/*
|
||||
* FNA bit 0 set to 1: all namespaces ... shall be configured with the same
|
||||
* attributes and a format (excluding secure erase) of any namespace results in a
|
||||
|
@ -7697,7 +7713,8 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
|
|||
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
|
||||
_cleanup_free_ struct nvme_nvm_id_ns *nvm_ns = NULL;
|
||||
_cleanup_free_ struct nvme_id_ns *ns = NULL;
|
||||
__u8 lba_index, ms = 0, sts = 0, pif = 0;
|
||||
__u8 lba_index, sts = 0, pif = 0;
|
||||
__u16 ms;
|
||||
|
||||
const char *start_block_addr = "64-bit addr of first block to access";
|
||||
const char *data_size = "size of data in bytes";
|
||||
|
@ -7882,7 +7899,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
|
|||
|
||||
nvme_id_ns_flbas_to_lbaf_inuse(ns->flbas, &lba_index);
|
||||
logical_block_size = 1 << ns->lbaf[lba_index].ds;
|
||||
ms = ns->lbaf[lba_index].ms;
|
||||
ms = le16_to_cpu(ns->lbaf[lba_index].ms);
|
||||
|
||||
nvm_ns = nvme_alloc(sizeof(*nvm_ns));
|
||||
if (!nvm_ns)
|
||||
|
@ -9158,18 +9175,90 @@ static int check_dhchap_key(int argc, char **argv, struct command *command, stru
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int append_keyfile(const char *keyring, long id, const char *keyfile)
|
||||
{
|
||||
_cleanup_free_ unsigned char *key_data = NULL;
|
||||
_cleanup_free_ char *exported_key = NULL;
|
||||
_cleanup_free_ char *identity = NULL;
|
||||
_cleanup_file_ FILE *fd = NULL;
|
||||
int err, ver, hmac, key_len;
|
||||
mode_t old_umask;
|
||||
long kr_id;
|
||||
char type;
|
||||
|
||||
kr_id = nvme_lookup_keyring(keyring);
|
||||
if (kr_id <= 0) {
|
||||
nvme_show_error("Failed to lookup keyring '%s', %s",
|
||||
keyring, strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
identity = nvme_describe_key_serial(id);
|
||||
if (!identity) {
|
||||
nvme_show_error("Failed to get identity info, %s",
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (sscanf(identity, "NVMe%01d%c%02d %*s", &ver, &type, &hmac) != 3) {
|
||||
nvme_show_error("Failed to parse identity\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
key_data = nvme_read_key(kr_id, id, &key_len);
|
||||
if (!key_data) {
|
||||
nvme_show_error("Failed to read back derive TLS PSK, %s",
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
exported_key = nvme_export_tls_key_versioned(ver, hmac,
|
||||
key_data, key_len);
|
||||
if (!exported_key) {
|
||||
nvme_show_error("Failed to export key, %s",
|
||||
strerror(errno));
|
||||
return -errno;
|
||||
}
|
||||
|
||||
old_umask = umask(0);
|
||||
|
||||
fd = fopen(keyfile, "a");
|
||||
if (!fd) {
|
||||
nvme_show_error("Failed to open '%s', %s",
|
||||
keyfile, strerror(errno));
|
||||
err = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = fprintf(fd, "%s %s\n", identity, exported_key);
|
||||
if (err < 0) {
|
||||
nvme_show_error("Failed to append key to '%', %s",
|
||||
keyfile, strerror(errno));
|
||||
err = -errno;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
chmod(keyfile, 0600);
|
||||
umask(old_umask);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int gen_tls_key(int argc, char **argv, struct command *command, struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Generate a TLS key in NVMe PSK Interchange format.";
|
||||
const char *secret =
|
||||
"Optional secret (in hexadecimal characters) to be used for the TLS key.";
|
||||
const char *hmac = "HMAC function to use for the retained key (1 = SHA-256, 2 = SHA-384).";
|
||||
const char *identity = "TLS identity version to use (0 = NVMe TCP 1.0c, 1 = NVMe TCP 2.0";
|
||||
const char *version = "TLS identity version to use (0 = NVMe TCP 1.0c, 1 = NVMe TCP 2.0";
|
||||
const char *hostnqn = "Host NQN for the retained key.";
|
||||
const char *subsysnqn = "Subsystem NQN for the retained key.";
|
||||
const char *keyring = "Keyring for the retained key.";
|
||||
const char *keytype = "Key type of the retained key.";
|
||||
const char *insert = "Insert retained key into the keyring.";
|
||||
const char *keyfile = "Update key file with the derive TLS PSK.";
|
||||
|
||||
_cleanup_free_ unsigned char *raw_secret = NULL;
|
||||
_cleanup_free_ char *encoded_key = NULL;
|
||||
|
@ -9184,8 +9273,9 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
|
|||
char *hostnqn;
|
||||
char *subsysnqn;
|
||||
char *secret;
|
||||
unsigned int hmac;
|
||||
unsigned int identity;
|
||||
char *keyfile;
|
||||
unsigned char hmac;
|
||||
unsigned char version;
|
||||
bool insert;
|
||||
};
|
||||
|
||||
|
@ -9195,8 +9285,9 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
|
|||
.hostnqn = NULL,
|
||||
.subsysnqn = NULL,
|
||||
.secret = NULL,
|
||||
.keyfile = NULL,
|
||||
.hmac = 1,
|
||||
.identity = 0,
|
||||
.version = 0,
|
||||
.insert = false,
|
||||
};
|
||||
|
||||
|
@ -9206,8 +9297,9 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
|
|||
OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
|
||||
OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
|
||||
OPT_STR("secret", 's', &cfg.secret, secret),
|
||||
OPT_UINT("hmac", 'm', &cfg.hmac, hmac),
|
||||
OPT_UINT("identity", 'I', &cfg.identity, identity),
|
||||
OPT_STR("keyfile", 'f', &cfg.keyfile, keyfile),
|
||||
OPT_BYTE("hmac", 'm', &cfg.hmac, hmac),
|
||||
OPT_BYTE("identity", 'I', &cfg.version, version),
|
||||
OPT_FLAG("insert", 'i', &cfg.insert, insert));
|
||||
|
||||
err = parse_args(argc, argv, desc, opts);
|
||||
|
@ -9217,9 +9309,9 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
|
|||
nvme_show_error("Invalid HMAC identifier %u", cfg.hmac);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cfg.identity > 1) {
|
||||
if (cfg.version > 1) {
|
||||
nvme_show_error("Invalid TLS identity version %u",
|
||||
cfg.identity);
|
||||
cfg.version);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (cfg.insert) {
|
||||
|
@ -9271,15 +9363,22 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl
|
|||
if (cfg.insert) {
|
||||
tls_key = nvme_insert_tls_key_versioned(cfg.keyring,
|
||||
cfg.keytype, cfg.hostnqn,
|
||||
cfg.subsysnqn, cfg.identity,
|
||||
cfg.subsysnqn, cfg.version,
|
||||
cfg.hmac, raw_secret, key_len);
|
||||
if (tls_key < 0) {
|
||||
if (tls_key <= 0) {
|
||||
nvme_show_error("Failed to insert key, error %d", errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
printf("Inserted TLS key %08x\n", (unsigned int)tls_key);
|
||||
|
||||
if (cfg.keyfile) {
|
||||
err = append_keyfile(cfg.keyring, tls_key, cfg.keyfile);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -9293,6 +9392,7 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
|
|||
const char *keyring = "Keyring for the retained key.";
|
||||
const char *keytype = "Key type of the retained key.";
|
||||
const char *insert = "Insert retained key into the keyring.";
|
||||
const char *keyfile = "Update key file with the derive TLS PSK.";
|
||||
|
||||
_cleanup_free_ unsigned char *decoded_key = NULL;
|
||||
_cleanup_free_ char *hnqn = NULL;
|
||||
|
@ -9305,7 +9405,8 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
|
|||
char *hostnqn;
|
||||
char *subsysnqn;
|
||||
char *keydata;
|
||||
unsigned int identity;
|
||||
char *keyfile;
|
||||
unsigned char identity;
|
||||
bool insert;
|
||||
};
|
||||
|
||||
|
@ -9315,6 +9416,7 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
|
|||
.hostnqn = NULL,
|
||||
.subsysnqn = NULL,
|
||||
.keydata = NULL,
|
||||
.keyfile = NULL,
|
||||
.identity = 0,
|
||||
.insert = false,
|
||||
};
|
||||
|
@ -9325,7 +9427,8 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
|
|||
OPT_STR("hostnqn", 'n', &cfg.hostnqn, hostnqn),
|
||||
OPT_STR("subsysnqn", 'c', &cfg.subsysnqn, subsysnqn),
|
||||
OPT_STR("keydata", 'd', &cfg.keydata, keydata),
|
||||
OPT_UINT("identity", 'I', &cfg.identity, identity),
|
||||
OPT_STR("keyfile", 'f', &cfg.keyfile, keyfile),
|
||||
OPT_BYTE("identity", 'I', &cfg.identity, identity),
|
||||
OPT_FLAG("insert", 'i', &cfg.insert, insert));
|
||||
|
||||
err = parse_args(argc, argv, desc, opts);
|
||||
|
@ -9366,11 +9469,17 @@ static int check_tls_key(int argc, char **argv, struct command *command, struct
|
|||
cfg.keytype, cfg.hostnqn,
|
||||
cfg.subsysnqn, cfg.identity,
|
||||
hmac, decoded_key, decoded_len);
|
||||
if (tls_key < 0) {
|
||||
if (tls_key <= 0) {
|
||||
nvme_show_error("Failed to insert key, error %d", errno);
|
||||
return -errno;
|
||||
}
|
||||
printf("Inserted TLS key %08x\n", (unsigned int)tls_key);
|
||||
|
||||
if (cfg.keyfile) {
|
||||
err = append_keyfile(cfg.keyring, tls_key, cfg.keyfile);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
} else {
|
||||
_cleanup_free_ char *tls_id = NULL;
|
||||
|
||||
|
@ -9394,11 +9503,18 @@ static void __scan_tls_key(long keyring_id, long key_id,
|
|||
_cleanup_free_ const unsigned char *key_data = NULL;
|
||||
_cleanup_free_ char *encoded_key = NULL;
|
||||
int key_len;
|
||||
int ver, hmac;
|
||||
char type;
|
||||
|
||||
key_data = nvme_read_key(keyring_id, key_id, &key_len);
|
||||
if (!key_data)
|
||||
return;
|
||||
encoded_key = nvme_export_tls_key(key_data, key_len);
|
||||
|
||||
if (sscanf(desc, "NVMe%01d%c%02d %*s", &ver, &type, &hmac) != 3)
|
||||
return;
|
||||
|
||||
encoded_key = nvme_export_tls_key_versioned(ver, hmac,
|
||||
key_data, key_len);
|
||||
if (!encoded_key)
|
||||
return;
|
||||
fprintf(fd, "%s %s\n", desc, encoded_key);
|
||||
|
@ -9456,6 +9572,7 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
|
|||
const char *revoke = "Revoke key from the keyring.";
|
||||
|
||||
_cleanup_file_ FILE *fd = NULL;
|
||||
mode_t old_umask = 0;
|
||||
int cnt, err = 0;
|
||||
|
||||
struct config {
|
||||
|
@ -9496,9 +9613,11 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
|
|||
else
|
||||
mode = "w";
|
||||
|
||||
old_umask = umask(0);
|
||||
|
||||
fd = fopen(cfg.keyfile, mode);
|
||||
if (!fd) {
|
||||
nvme_show_error("Cannot open keyfile %s, error %d\n",
|
||||
nvme_show_error("Cannot open keyfile %s, error %d",
|
||||
cfg.keyfile, errno);
|
||||
return -errno;
|
||||
}
|
||||
|
@ -9519,16 +9638,41 @@ static int tls_key(int argc, char **argv, struct command *command, struct plugin
|
|||
return -EINVAL;
|
||||
} else if (cfg.export) {
|
||||
err = nvme_scan_tls_keys(cfg.keyring, __scan_tls_key, fd);
|
||||
if (err)
|
||||
if (err < 0) {
|
||||
nvme_show_error("Export of TLS keys failed with '%s'",
|
||||
nvme_strerror(errno));
|
||||
return err;
|
||||
}
|
||||
|
||||
if (argconfig_parse_seen(opts, "verbose"))
|
||||
printf("exporting to %s\n", cfg.keyfile);
|
||||
|
||||
return 0;
|
||||
} else if (cfg.import) {
|
||||
err = import_key(cfg.keyring, fd);
|
||||
if (err) {
|
||||
nvme_show_error("Import of TLS keys failed with '%s'",
|
||||
nvme_strerror(errno));
|
||||
return err;
|
||||
}
|
||||
|
||||
if (argconfig_parse_seen(opts, "verbose"))
|
||||
printf("importing from %s\n", cfg.keyfile);
|
||||
} else {
|
||||
err = nvme_revoke_tls_key(cfg.keyring, cfg.keytype, cfg.revoke);
|
||||
if (err)
|
||||
if (err) {
|
||||
nvme_show_error("Failed to revoke key '%s'",
|
||||
nvme_strerror(errno));
|
||||
return err;
|
||||
}
|
||||
|
||||
if (argconfig_parse_seen(opts, "verbose"))
|
||||
printf("revoking key\n");
|
||||
}
|
||||
|
||||
if (old_umask != 0 && fd) {
|
||||
umask(old_umask);
|
||||
chmod(cfg.keyfile, 0600);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue