return encoded_key;
}
+
+unsigned char *nvme_import_tls_key(const char *encoded_key, int *key_len,
+ unsigned int *hmac)
+{
+ unsigned char decoded_key[128], *key_data;
+ unsigned int crc = crc32(0L, NULL, 0);
+ unsigned int key_crc;
+ int err, decoded_len;
+
+ if (sscanf(encoded_key, "NVMeTLSkey-1:%02x:*s", &err) != 1) {
+ errno = EINVAL;
+ return NULL;
+ }
+ switch (err) {
+ case 1:
+ if (strlen(encoded_key) != 65) {
+ errno = EINVAL;
+ return NULL;
+ }
+ break;
+ case 2:
+ if (strlen(encoded_key) != 89) {
+ errno = EINVAL;
+ return NULL;
+ }
+ break;
+ default:
+ errno = EINVAL;
+ return NULL;
+ }
+
+ *hmac = err;
+ err = base64_decode(encoded_key + 16, strlen(encoded_key) - 17,
+ decoded_key);
+ if (err < 0) {
+ errno = ENOKEY;
+ return NULL;
+ }
+ decoded_len = err;
+ decoded_len -= 4;
+ if (decoded_len != 32 && decoded_len != 48) {
+ errno = ENOKEY;
+ return NULL;
+ }
+ crc = crc32(crc, decoded_key, decoded_len);
+ key_crc = ((u_int32_t)decoded_key[decoded_len]) |
+ ((u_int32_t)decoded_key[decoded_len + 1] << 8) |
+ ((u_int32_t)decoded_key[decoded_len + 2] << 16) |
+ ((u_int32_t)decoded_key[decoded_len + 3] << 24);
+ if (key_crc != crc) {
+ nvme_msg(NULL, LOG_ERR, "CRC mismatch (key %08x, crc %08x)",
+ key_crc, crc);
+ errno = ENOKEY;
+ return NULL;
+ }
+
+ key_data = malloc(decoded_len);
+ if (!key_data) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ memcpy(key_data, decoded_key, decoded_len);
+
+ *key_len = decoded_len;
+ return key_data;
+}
*/
char *nvme_export_tls_key(const unsigned char *key_data, int key_len);
+/**
+ * nvme_import_tls_key() - Import a TLS key
+ * @encoded_key: TLS key in PSK interchange format
+ * @key_len: Length of the resulting key data
+ * @hmac: HMAC algorithm
+ *
+ * Imports @key_data in the PSK Interchange format as defined in section
+ * 3.6.1.5 of the NVMe TCP Transport specification.
+ *
+ * Return: The raw data of the PSK or NULL with errno set on error. It is
+ * the responsibility of the caller to free the returned string.
+ */
+unsigned char *nvme_import_tls_key(const char *encoded_key, int *key_len,
+ unsigned int *hmac);
+
/**
* nvme_submit_passthru - Low level ioctl wrapper for passthru commands
* @fd: File descriptor of the nvme device