diff --git a/src/libnvme.map b/src/libnvme.map index 29efc5d6..742f6356 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -4,6 +4,7 @@ LIBNVME_1_7 { nvme_init_copy_range_f2; nvme_init_copy_range_f3; nvme_insert_tls_key_versioned; + nvme_generate_tls_key_identity; }; LIBNVME_1_6 { diff --git a/src/nvme/linux.c b/src/nvme/linux.c index 6433899d..bd1f7ca5 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -1231,6 +1231,38 @@ long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type, return key; } +char *nvme_generate_tls_key_identity(const char *hostnqn, const char *subsysnqn, + int version, int hmac, + unsigned char *configured_key, int key_len) +{ + char *identity; + size_t identity_len; + unsigned char *psk; + int ret; + + identity_len = nvme_identity_len(hmac, version, hostnqn, subsysnqn); + if (identity_len < 0) + return NULL; + + identity = malloc(identity_len); + if (!identity) + return NULL; + + psk = malloc(key_len); + if (!psk) + goto out_free_identity; + + memset(psk, 0, key_len); + ret = derive_nvme_keys(hostnqn, subsysnqn, identity, version, hmac, + configured_key, psk, key_len); + free(psk); +out_free_identity: + if (ret < 0) { + free(identity); + identity = NULL; + } + return identity; +} #else long nvme_lookup_keyring(const char *keyring) { @@ -1274,6 +1306,16 @@ long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type, errno = ENOTSUP; return -1; } + +char *nvme_generate_tls_key_identity(const char *hostnqn, const char *subsysnqn, + int version, int hmac, + unsigned char *configured_key, int key_len) +{ + nvme_msg(NULL, LOG_ERR, "key operations not supported; " \ + "recompile with keyutils support.\n"); + errno = ENOTSUP; + return -1; +} #endif long nvme_insert_tls_key(const char *keyring, const char *key_type, diff --git a/src/nvme/linux.h b/src/nvme/linux.h index c593c9de..11ee76e2 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -316,4 +316,23 @@ long nvme_insert_tls_key_versioned(const char *keyring, const char *key_type, int version, int hmac, unsigned char *configured_key, int key_len); +/** + * nvme_generate_tls_key_identity() - Generate the TLS key identity + * @hostnqn: Host NVMe Qualified Name + * @subsysnqn: Subsystem NVMe Qualified Name + * @version: Key version to use + * @hmac: HMAC algorithm + * @configured_key: Configured key data to derive the key from + * @key_len: Length of @configured_key + * + * Derives a 'retained' TLS key as specified in NVMe TCP and + * generate the corresponding TLs identity. + * + * Return: The string containing the TLS identity. It is the responsibility + * of the caller to free the returned string. + */ +char *nvme_generate_tls_key_identity(const char *hostnqn, const char *subsysnqn, + int version, int hmac, + unsigned char *configured_key, int key_len); + #endif /* _LIBNVME_LINUX_H */