Commit 5cddbe2a authored by Marcin Galecki's avatar Marcin Galecki Committed by Tomasz Zawadzki
Browse files

nvme/auth: make sure spdk_nvme_dhchap_dhkey_get_pubkey returns valid key length



Occasionally DHVLEN sent by nvme_auth_send_reply() is incorrect.

By NVMe spec "DHVLEN shall be a multiple of 4", but spdk_nvme_dhchap_dhkey_get_pubkey()
sometimes returns key length 1023 where expected is 1024, 511 instead of 512 etc.

Issue occurs because BN_num_bytes() doesn't count for unsignificant bits.
The solution is to use EVP_PKEY_get_bits() to get key length.

Fixes #3400

Change-Id: I0222f9e78310c92e05e9e1de1b976a5af83913ac
Signed-off-by: default avatarMarcin Galecki <marcin.galecki@dell.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/23562


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent e55c9a81
Loading
Loading
Loading
Loading
+15 −9
Original line number Diff line number Diff line
@@ -528,24 +528,30 @@ spdk_nvme_dhchap_dhkey_get_pubkey(struct spdk_nvme_dhchap_dhkey *dhkey, void *pu
	EVP_PKEY *key = (EVP_PKEY *)dhkey;
	BIGNUM *bn = NULL;
	int rc;
	const size_t num_bytes = (size_t)spdk_divide_round_up(EVP_PKEY_get_bits(key), 8);

	if (num_bytes == 0) {
		SPDK_ERRLOG("Failed to get key size\n");
		return -EIO;
	}

	if (num_bytes > *len) {
		SPDK_ERRLOG("Insufficient key buffer size=%zu (needed=%zu)",
			    *len, num_bytes);
		return -EINVAL;
	}
	*len = num_bytes;

	if (EVP_PKEY_get_bn_param(key, "pub", &bn) != 1) {
		rc = -EIO;
		goto error;
	}
	if ((size_t)BN_num_bytes(bn) > *len) {
		SPDK_ERRLOG("Insufficient key buffer size=%zu (needed=%d)",
			    *len, BN_num_bytes(bn));
		rc = -EINVAL;
		goto error;
	}
	rc = BN_bn2bin(bn, pub);

	rc = BN_bn2binpad(bn, pub, *len);
	if (rc <= 0) {
		rc = -EIO;
		goto error;
	}

	*len = (size_t)BN_num_bytes(bn);
	rc = 0;
error:
	BN_free(bn);