From: Hannes Reinecke Date: Wed, 22 Mar 2023 14:58:27 +0000 (+0100) Subject: nvme-gen-tls-key: add options to derive a TLS key X-Git-Tag: v2.4~8 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=f577d75aa2313a22f801c11ca2fe947396525acb;p=users%2Fsagi%2Fnvme-cli.git nvme-gen-tls-key: add options to derive a TLS key Add options to derive a TLS key and store it into the given keyring. Signed-off-by: Hannes Reinecke --- diff --git a/Documentation/nvme-gen-tls-key.txt b/Documentation/nvme-gen-tls-key.txt index cfa86147..9a03e3ab 100644 --- a/Documentation/nvme-gen-tls-key.txt +++ b/Documentation/nvme-gen-tls-key.txt @@ -8,18 +8,52 @@ nvme-gen-tls-key - Generate a NVMe TLS PSK SYNOPSIS -------- [verse] -'nvme gen-tls-key' [--hmac= | -h ] +'nvme gen-tls-key' [--keyring= | -k ] + [--keytype= | -t ] + [--hostnqn= | -n ] + [--subsysnqn= | -c ] + [--hmac= | -h ] [--secret= | -s ] + [--insert | -i ] DESCRIPTION ----------- -Generate a base64-encoded NVMe TLS pre-shared key (PSK) in -the PSK interchange format -NVMeTLSkey-1:01:VRLbtnN9AQb2WXW3c9+wEf/DRLz0QuLdbYvEhwtdWwNf9LrZ: -and prints it to stdout. +Generate a base64-encoded NVMe TLS pre-shared key (PSK). +The resulting key is either printed in the PSK interchange format +'NVMeTLSkey-1:01::', +inserted as a 'retained' key into the specified keyring, or both. +When the PSK should be inserted into the keyring a 'retained' key +is derived from the secret key material, and the resulting 'retained' +key is stored with the identity +'NVMe0R0 ' +in the keyring. +The 'retained' key is derived from the secret key material, +the specified subsystem NQN, and the host NQN. +Once the 'retained' key is stored in the keyring the original +secret key material cannot be retrieved. OPTIONS ------- +-k :: +--keyring=:: + Name of the keyring into which the 'retained' TLS key should be + stored. Default is '.nvme'. + +-t :: +--keytype=:: + Type of the key for resulting TLS key. + Default is 'psk'. + +-n :: +--hostnqn=:: + Host NVMe Qualified Name (NQN) to be used to derive the + 'retained' TLS key + +-c :: +--subsysnqn=:: + Subsystem NVMe Qualified Name (NQN) to be used to derive the + 'retained' TLS key + -h :: --hmac=:: Select a HMAC algorithm to use. Possible values are: @@ -31,6 +65,11 @@ OPTIONS Secret value (in hexadecimal) to be used for the key. If none are provided a random value is used. +-i:: +--insert:: + Insert the resulting TLS key into the keyring without printing out + the key in PSK interchange format. + EXAMPLES -------- No Examples diff --git a/nvme.c b/nvme.c index a40a58c8..4c0d44ff 100644 --- a/nvme.c +++ b/nvme.c @@ -8827,26 +8827,47 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl "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 *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 only, do not print the retained key."; unsigned char *raw_secret; char encoded_key[128]; int key_len = 32; unsigned long crc = crc32(0L, NULL, 0); - int err = 0; + int err; + long tls_key; struct config { + char *keyring; + char *keytype; + char *hostnqn; + char *subsysnqn; char *secret; unsigned int hmac; + bool insert; }; struct config cfg = { + .keyring = ".nvme", + .keytype = "psk", + .hostnqn = NULL, + .subsysnqn = NULL, .secret = NULL, .hmac = 1, + .insert = false, }; OPT_ARGS(opts) = { + OPT_STR("keyring", 'k', &cfg.keyring, keyring), + OPT_STR("keytype", 't', &cfg.keytype, keytype), + 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_FLAG("insert", 'i', &cfg.insert, insert), OPT_END() }; @@ -8857,7 +8878,10 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl fprintf(stderr, "Invalid HMAC identifier %u\n", cfg.hmac); return -EINVAL; } - + if (cfg.insert && !cfg.subsysnqn) { + fprintf(stderr, "No subsystem NQN specified\n"); + return -EINVAL; + } if (cfg.hmac == 2) key_len = 48; @@ -8891,6 +8915,36 @@ static int gen_tls_key(int argc, char **argv, struct command *command, struct pl } } + if (cfg.hostnqn && !cfg.subsysnqn) { + fprintf(stderr, + "Need to specify subsystem NQN to insert a TLS key\n"); + return -EINVAL; + } + if (cfg.subsysnqn) { + if (!cfg.hostnqn) { + cfg.hostnqn = nvmf_hostnqn_from_file(); + if (!cfg.hostnqn) { + fprintf(stderr, + "Failed to read host NQN\n"); + return -EINVAL; + } + } + + tls_key = nvme_insert_tls_key(cfg.keyring, cfg.keytype, + cfg.hostnqn, cfg.subsysnqn, cfg.hmac, + raw_secret, key_len); + if (tls_key < 0) { + fprintf(stderr, + "Failed to insert key, error %d\n", errno); + return -errno; + } + + if (cfg.insert) { + printf("Inserted TLS key %08x\n", + (unsigned int)tls_key); + return 0; + } + } crc = crc32(crc, raw_secret, key_len); raw_secret[key_len++] = crc & 0xff; raw_secret[key_len++] = (crc >> 8) & 0xff;