Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/subprojects/*/
!/subprojects/packagefiles/
/build/*
/build_*/
/.vscode/*
/.cache/*
.*
Expand Down
19 changes: 11 additions & 8 deletions config.h.in
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@

#pragma once

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#define SPDMD_VERSION @SPDMD_VERSION@

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#define SPDM_WRAPPER_VERSION @SPDMD_VERSION@

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine FETCH_SERIALNUMBER_FROM_RESPONDER

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine DISCOVERY_ONLY_FROM_MCTP_CONTROL

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine SPDM_JSON_CONF_FILE_NAME

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine COMPOSITE_ATTESTER_BACKEND

// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine USE_DEFAULT_DBUS

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine USE_FUZZ

//NOLINTNEXTLINE cppcoreguidelines-macro-usage
// NOLINTNEXTLINE cppcoreguidelines-macro-usage
#mesondefine MCTP_IN_KERNEL

#mesondefine CSM_SERVICE_ENABLED
75 changes: 73 additions & 2 deletions libspdmcpp/connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
#include <bit>
#include <fstream>
#include <functional>
#include <mutex>
#include <ranges>
#include <type_traits>
#include <unordered_map>

// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define SPDMCPP_CONNECTION_RS_ERROR_RETURN(rs) \
Expand Down Expand Up @@ -88,6 +90,35 @@ namespace spdmcpp

namespace
{

std::mutex measurementSpecificationsMutex;
std::unordered_map<const ConnectionClass*, uint8_t>
connectionMeasurementSpecifications;

uint8_t getMeasurementSpecifications(const ConnectionClass* connection)
{
std::lock_guard lock(measurementSpecificationsMutex);
if (auto it = connectionMeasurementSpecifications.find(connection);
it != connectionMeasurementSpecifications.end())
{
return it->second;
}
return ConnectionClass::measurementSpecificationDmtf;
}

void setMeasurementSpecifications(const ConnectionClass* connection,
uint8_t specifications)
{
std::lock_guard lock(measurementSpecificationsMutex);
connectionMeasurementSpecifications[connection] = specifications;
}

void eraseMeasurementSpecifications(const ConnectionClass* connection)
{
std::lock_guard lock(measurementSpecificationsMutex);
connectionMeasurementSpecifications.erase(connection);
}

/**
* @param[in] RTDExp Exponent value of base wait time
* @param[in] RTDM RTDM multiplier for maximum allowed time
Expand All @@ -111,6 +142,19 @@ ConnectionClass::ConnectionClass(const ContextClass& cont, LogClass& log,
resetConnection();
}

ConnectionClass::ConnectionClass(const ContextClass& cont, LogClass& log,
uint8_t eid, std::string sockPath,
uint8_t measurementSpecifications) :
ConnectionClass(cont, log, eid, std::move(sockPath))
{
setMeasurementSpecifications(this, measurementSpecifications);
}

ConnectionClass::~ConnectionClass()
{
eraseMeasurementSpecifications(this);
}

RetStat ConnectionClass::refreshMeasurements(SlotIdx slotidx)
{
CertificateSlotIdx = slotidx;
Expand Down Expand Up @@ -179,6 +223,7 @@ void ConnectionClass::resetConnection()
respIfReqCode = 0;
respIfReadyToken = std::nullopt;
DMTFMeasurements.clear();
DeviceEatToken.clear();
MeasurementsHash.clear();
MeasurementsSignature.clear();
MeasurementNonce.fill(0);
Expand Down Expand Up @@ -537,7 +582,7 @@ RetStat ConnectionClass::tryNegotiateAlgorithms()

PacketNegotiateAlgorithmsRequestVar request;
request.Min.Header.MessageVersion = MessageVersion;
request.Min.MeasurementSpecification = 1 << 0;
request.Min.MeasurementSpecification = getMeasurementSpecifications(this);

request.Min.BaseAsymAlgo = BaseAsymAlgoFlags::TPM_ALG_ECDSA_ECC_NIST_P256 |
BaseAsymAlgoFlags::TPM_ALG_ECDSA_ECC_NIST_P384 |
Expand Down Expand Up @@ -591,6 +636,19 @@ RetStat ConnectionClass::handleRecv<PacketAlgorithmsResponseVar>()
rs = RetStat::ERROR_INVALID_RESERVED;
SPDMCPP_CONNECTION_RS_ERROR_RETURN_WITH_VERSION(rs);
}
const uint8_t selectedMeasurementSpecification =
resp.Min.MeasurementSpecification;
const uint8_t supportedMeasurementSpecifications =
getMeasurementSpecifications(this);
if ((!skipMeasurements() && selectedMeasurementSpecification == 0) ||
(selectedMeasurementSpecification != 0 &&
(std::popcount(selectedMeasurementSpecification) != 1 ||
(selectedMeasurementSpecification &
supportedMeasurementSpecifications) == 0)))
{
rs = RetStat::ERROR_WRONG_ALGO_BITS;
SPDMCPP_CONNECTION_RS_ERROR_RETURN_WITH_VERSION(rs);
}
if (std::popcount(
static_cast<std::underlying_type_t<MeasurementHashAlgoFlags>>(
resp.Min.MeasurementHashAlgo)) > 1)
Expand Down Expand Up @@ -958,7 +1016,13 @@ RetStat ConnectionClass::handleRecv<PacketMeasurementsResponseVar>()
// parse and store DMTF Measurements
for (const auto& block : resp.MeasurementBlockVector)
{
if (block.Min.MeasurementSpecification == 1)
if (block.Min.MeasurementSpecification !=
Algorithms.Min.MeasurementSpecification)
{
rs = RetStat::ERROR_WRONG_ALGO_BITS;
SPDMCPP_CONNECTION_RS_ERROR_RETURN_WITH_VERSION(rs);
}
if (block.Min.MeasurementSpecification == measurementSpecificationDmtf)
{
if (DMTFMeasurements.find(block.Min.Index) !=
DMTFMeasurements.end())
Expand All @@ -984,6 +1048,13 @@ RetStat ConnectionClass::handleRecv<PacketMeasurementsResponseVar>()
}
}
}
else if (block.Min.MeasurementSpecification ==
measurementSpecificationEat)
{
DeviceEatToken.insert(DeviceEatToken.end(),
block.MeasurementVector.begin(),
block.MeasurementVector.end());
}
}
// Reset index if used
if (requestedMeasurementIdx == 255)
Expand Down
39 changes: 33 additions & 6 deletions libspdmcpp/headers_public/spdmcpp/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ class ConnectionClass : public NonCopyable
* DSP0274_1.1.1 page 56 */
static constexpr SlotIdx slotNum = 8;

static constexpr uint8_t measurementSpecificationDmtf = 1U << 0U;
static constexpr uint8_t measurementSpecificationEat = 1U << 1U;

/** @brief Main constructor
* @param[in] context - Context containing various common configuration and
* information
Expand All @@ -162,7 +165,12 @@ class ConnectionClass : public NonCopyable
explicit ConnectionClass(const ContextClass& context, LogClass& log,
uint8_t eid, std::string sockPath);

~ConnectionClass() = default;
/** @brief Constructor with explicit requester measurement specifications.
*/
ConnectionClass(const ContextClass& context, LogClass& log, uint8_t eid,
std::string sockPath, uint8_t measurementSpecifications);

~ConnectionClass();

/** @brief get send timeout during the connection
*
Expand Down Expand Up @@ -339,6 +347,13 @@ class ConnectionClass : public NonCopyable
return toHash(Algorithms.Min.MeasurementHashAlgo);
}

/** @brief Negotiated MeasurementSpecification from ALGORITHMS. */
uint8_t getMeasurementSpecification() const
{
SPDMCPP_ASSERT(hasInfo(ConnectionInfoEnum::ALGORITHMS));
return Algorithms.Min.MeasurementSpecification;
}

/** @brief Capabilities flag for responder capabilities
*
*/
Expand All @@ -356,11 +371,9 @@ class ConnectionClass : public NonCopyable
return MessageVersion;
}

/** @brief Returns the certificate chain for the given slot index
* @details Note this function will return false if the certificate chain
* was not fetched for the given slot (even if it is available on the device
* itself)
* @param[out] buf - the buffer into which the certificate chain is written
/** @brief Returns the DER certificate chain for the given slot index
* @details This strips the SPDM certificate-chain header and RootHash.
* @param[out] buf - the buffer into which the DER chain is written
* @returns true if the certificate chain was available and written into
* buf, false otherwise
*/
Expand Down Expand Up @@ -417,6 +430,12 @@ class ConnectionClass : public NonCopyable

return CombinedMeasurementTranscript;
}

/** @brief VERSION, CAPABILITIES, and ALGORITHMS request/response bytes. */
const std::vector<uint8_t>& getVcaTranscript() const
{
return refBuf(BufEnum::A);
Comment thread
helloxiling marked this conversation as resolved.
}
/** @brief The L1/L2 hash of the measurements, as returned by
* getSignedMeasurementsBuffer()
*/
Expand All @@ -432,6 +451,11 @@ class ConnectionClass : public NonCopyable
{
return MeasurementsSignature;
}
/** @brief Reassembled EAT token bytes from EAT measurement blocks. */
const std::vector<uint8_t>& getDeviceEatToken() const
{
return DeviceEatToken;
}
const nonce_array_32& getMeasurementNonce() const
{
return MeasurementNonce;
Expand Down Expand Up @@ -780,6 +804,9 @@ class ConnectionClass : public NonCopyable
*/
DMTFMeasurementsContainer DMTFMeasurements;

/** @brief Storage for reassembled EAT measurement-block payloads. */
std::vector<uint8_t> DeviceEatToken;

/** @brief Storage for the final L1/L2 hash
*/
std::vector<uint8_t> MeasurementsHash;
Expand Down
Loading