bool spdm_check_request_flag_compatibility()

in core/spdm/spdm_commands.c [173:246]


bool spdm_check_request_flag_compatibility (struct spdm_get_capabilities_flags_format flags,
	uint8_t version)
{
	/* Illegal to return reserved values. */
	if (flags.psk_cap >= SPDM_PSK_RESERVED) {
		return false;
	}

	/* Key exchange capabilities checks. */
	if ((flags.key_ex_cap == 1) || (flags.psk_cap == SPDM_PSK_SUPPORTED_NO_CONTEXT)) {
		/* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, the SPDM
		 * responder also implements DSP0277 secure messages, which requires at least MAC_CAP
		 * to be set. */
		if (flags.mac_cap == 0) {
			return false;
		}
	}
	else {
		/* mac_cap, encrypt_cap and key_upd_cap capabilities require either key exchange
		 * or pre-shared key capability.
		 *
		 * heartbeat messages are sent in a secure session, the setup of which also require
		 * either key exchange or pre-shared key capability.
		 *
		 * handshake_in_the_clear_cap requires key_ex_cap. */
		if ((flags.mac_cap == 1) || (flags.encrypt_cap == 1) ||
			(flags.handshake_in_the_clear_cap == 1) || (flags.hbeat_cap == 1) ||
			(flags.key_upd_cap == 1)) {
			return false;
		}
	}
	/* This is per libSPDM, so keeping this check. */
	if ((flags.key_ex_cap == 0) && (flags.psk_cap == SPDM_PSK_SUPPORTED_NO_CONTEXT) &&
		(flags.handshake_in_the_clear_cap == 1)) {
		return false;
	}

	/* Certificate or public key capabilities checks. */
	if ((flags.cert_cap == 1) || (flags.pub_key_id_cap == 1)) {
		/* Certificate capabilities and public key capabilities cannot both be set. */
		if ((flags.cert_cap == 1) && (flags.pub_key_id_cap == 1)) {
			return false;
		}

		/* cert_cap and/or pub_key_id_cap are not needed if both chal_cap and key_ex_cap are 0.
		 * Theoretically, this might be ok, but libSPDM has this check, so keeping it.
		 *
		 * TODO:  This needs to be re-evaluated.  There is no requirement per the SPDM spec for this
		 * check as there is no specified coupling between certificate and challenge/key exchange
		 * support.  It's reasonable to envision an implementation that doesn't support challenge
		 * but supports measurement signing. */
		if ((flags.chal_cap == 0) && (flags.key_ex_cap == 0)) {
			return false;
		}
	}
	else {
		/**
		 * If certificates or public keys are not enabled, then these capabilities
		 * cannot be enabled. */
		if ((flags.chal_cap == 1) || (flags.mut_auth_cap == 1)) {
			return false;
		}
	}

	/* Checks specific to v1.1. */
	if (version == SPDM_VERSION_1_1) {
		/* Having mut_auth_cap requires encap_cap to be available. */
		if ((flags.mut_auth_cap == 1) && (flags.encap_cap == 0)) {
			return false;
		}
	}

	return true;
}