Commit ab93bb4e authored by Konrad Sztyber's avatar Konrad Sztyber Committed by Tomasz Zawadzki
Browse files

nvme/auth: limit allowed digests/dhgroups



Users can now limit the allowed digests/dhgroups used for in-band
authentication.  By default, all supported digests/dhgroups are allowed.

Signed-off-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Change-Id: Ife63c93a72b2d0fa75ea70c3aefa6750555aae99
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/22017


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
parent 979f5511
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -295,8 +295,20 @@ struct spdk_nvme_ctrlr_opts {
	 * In-band authentication DH-HMAC-CHAP key.
	 */
	struct spdk_key *dhchap_key;

	/**
	 * Allowed digests in in-band authentication.  Each bit corresponds to one of the
	 * spdk_nvmf_dhchap_hash values.
	 */
	uint32_t dhchap_digests;

	/**
	 * Allowed Diffie-Hellman groups in in-band authentication.  Each bit corresponds to one of
	 * the spdk_nvmf_dhchap_dhgroup values.
	 */
	uint32_t dhchap_dhgroups;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_opts) == 840, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ctrlr_opts) == 848, "Incorrect size");

/**
 * NVMe acceleration operation callback.
+2 −0
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ extern "C" {
#define SPDK_ALIGN_CEIL(val, align) \
	SPDK_ALIGN_FLOOR(((val) + ((__typeof__(val)) (align) - 1)), align)

#define SPDK_BIT(n) (1ul << (n))

uint32_t spdk_u32log2(uint32_t x);

static inline uint32_t
+2 −0
Original line number Diff line number Diff line
@@ -971,6 +971,8 @@ nvme_ctrlr_opts_init(struct spdk_nvme_ctrlr_opts *opts,
	SET_FIELD_ARRAY(psk);
	SET_FIELD(tls_psk);
	SET_FIELD(dhchap_key);
	SET_FIELD(dhchap_digests);
	SET_FIELD(dhchap_dhgroups);

#undef FIELD_OK
#undef SET_FIELD
+44 −8
Original line number Diff line number Diff line
@@ -97,6 +97,22 @@ nvme_auth_get_dhgroup_name(int id)
	return NULL;
}

static bool
nvme_auth_digest_allowed(struct spdk_nvme_qpair *qpair, uint8_t digest)
{
	struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;

	return ctrlr->opts.dhchap_digests & SPDK_BIT(digest);
}

static bool
nvme_auth_dhgroup_allowed(struct spdk_nvme_qpair *qpair, uint8_t dhgroup)
{
	struct spdk_nvme_ctrlr *ctrlr = qpair->ctrlr;

	return ctrlr->opts.dhchap_dhgroups & SPDK_BIT(dhgroup);
}

static void
nvme_auth_set_state(struct spdk_nvme_qpair *qpair, enum nvme_qpair_auth_state state)
{
@@ -681,16 +697,24 @@ nvme_auth_send_negotiate(struct spdk_nvme_qpair *qpair)

	memset(qpair->poll_status->dma_data, 0, NVME_AUTH_DATA_SIZE);
	desc->auth_id = SPDK_NVMF_AUTH_TYPE_DHCHAP;
	desc->halen = SPDK_COUNTOF(g_digests);
	desc->dhlen = SPDK_COUNTOF(g_dhgroups);
	assert(SPDK_COUNTOF(g_digests) <= sizeof(desc->hash_id_list));
	assert(SPDK_COUNTOF(g_dhgroups) <= sizeof(desc->dhg_id_list));

	assert(desc->halen <= sizeof(desc->hash_id_list));
	assert(desc->dhlen <= sizeof(desc->dhg_id_list));
	for (i = 0; i < desc->halen; ++i) {
		desc->hash_id_list[i] = g_digests[i].id;
	for (i = 0; i < SPDK_COUNTOF(g_digests); ++i) {
		if (!nvme_auth_digest_allowed(qpair, g_digests[i].id)) {
			continue;
		}
		AUTH_DEBUGLOG(qpair, "digest: %u (%s)\n", g_digests[i].id,
			      nvme_auth_get_digest_name(g_digests[i].id));
		desc->hash_id_list[desc->halen++] = g_digests[i].id;
	}
	for (i = 0; i < desc->dhlen; ++i) {
		desc->dhg_id_list[i] = g_dhgroups[i].id;
	for (i = 0; i < SPDK_COUNTOF(g_dhgroups); ++i) {
		if (!nvme_auth_dhgroup_allowed(qpair, g_dhgroups[i].id)) {
			continue;
		}
		AUTH_DEBUGLOG(qpair, "dhgroup: %u (%s)\n", g_dhgroups[i].id,
			      nvme_auth_get_dhgroup_name(g_dhgroups[i].id));
		desc->dhg_id_list[desc->dhlen++] = g_dhgroups[i].id;
	}

	msg->auth_type = SPDK_NVMF_AUTH_TYPE_COMMON_MESSAGE;
@@ -764,6 +788,18 @@ nvme_auth_check_challenge(struct spdk_nvme_qpair *qpair)
		goto error;
	}

	if (!nvme_auth_digest_allowed(qpair, challenge->hash_id)) {
		AUTH_ERRLOG(qpair, "received disallowed digest: %u (%s)\n", challenge->hash_id,
			    nvme_auth_get_digest_name(challenge->hash_id));
		goto error;
	}

	if (!nvme_auth_dhgroup_allowed(qpair, challenge->dhg_id)) {
		AUTH_ERRLOG(qpair, "received disallowed dhgroup: %u (%s)\n", challenge->dhg_id,
			    nvme_auth_get_dhgroup_name(challenge->dhg_id));
		goto error;
	}

	return 0;
error:
	nvme_auth_set_failure(qpair, -EACCES,
+11 −0
Original line number Diff line number Diff line
@@ -235,6 +235,17 @@ spdk_nvme_ctrlr_get_default_ctrlr_opts(struct spdk_nvme_ctrlr_opts *opts, size_t
	SET_FIELD(disable_read_changed_ns_list_log_page, false);
	SET_FIELD(tls_psk, NULL);
	SET_FIELD(dhchap_key, NULL);
	SET_FIELD(dhchap_digests,
		  SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA256) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA384) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_HASH_SHA512));
	SET_FIELD(dhchap_dhgroups,
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_NULL) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_2048) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_3072) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_4096) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_6144) |
		  SPDK_BIT(SPDK_NVMF_DHCHAP_DHGROUP_8192));

	if (FIELD_OK(psk)) {
		memset(opts->psk, 0, sizeof(opts->psk));