cryptnox-sdk-cpp 1.0.0
Platform-independent C++ core SDK for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
CW_SecureChannel Class Reference

Implements the Cryptnox secure channel protocol over NFC. More...

#include <CW_SecureChannel.h>

Collaboration diagram for CW_SecureChannel:
[legend]

Public Member Functions

 CW_SecureChannel (CW_NfcTransport &driver, CW_Logger &logger, CW_CryptoProvider &crypto, CW_Platform &platform)
 Construct a CW_SecureChannel.
 CW_SecureChannel (const CW_SecureChannel &)=delete
CW_SecureChanneloperator= (const CW_SecureChannel &)=delete
bool begin ()
 Initialize the NFC transport module.
bool inListPassiveTarget ()
 Detect a passive NFC target (ISO-DEP card).
void resetReader ()
 Reset the NFC reader hardware.
bool printFirmwareVersion ()
 Print the NFC reader firmware version to the logger.
bool selectApdu ()
 Send the SELECT APDU to activate the Cryptnox application.
bool getCardCertificate (uint8_t *cardCertificate, uint8_t &cardCertificateLength)
 Retrieve the card's ephemeral public key via GET CARD CERTIFICATE.
bool extractCardEphemeralKey (const uint8_t *cardCertificate, uint8_t *cardEphemeralPubKey, uint8_t *fullEphemeralPubKey65=NULL)
 Extract the card's ephemeral EC P-256 public key from a certificate.
bool openSecureChannel (uint8_t *salt, uint8_t *clientPublicKey, uint8_t *clientPrivateKey, CW_Curve sessionCurve)
 Send OPEN SECURE CHANNEL and retrieve the session salt.
bool mutuallyAuthenticate (CW_SecureSession &session, const uint8_t *salt, uint8_t *clientPublicKey, const uint8_t *clientPrivateKey, CW_Curve sessionCurve, const uint8_t *cardEphemeralPubKey)
 Perform ECDH derivation and MUTUALLY AUTHENTICATE with the card.
bool getManufacturerCertificate (uint8_t *cert, uint16_t &certLen)
 Retrieve the manufacturer certificate stored in card flash.
bool preFetchManufacturerCert ()
 Fetch and cache the manufacturer certificate before getCardCertificate().
uint8_t verifyCertificateChain (const uint8_t *cardCert, uint8_t cardCertLen)
 Verify the full card certificate chain against the trusted CA.
bool aesCbcEncrypt (CW_SecureSession &session, const uint8_t apdu[], uint16_t apduLength, const uint8_t data[], uint16_t dataLength, uint8_t *decryptedOutput=NULL, uint16_t *decryptedOutputLength=NULL)
 AES-CBC encrypt + MAC, send APDU, and decrypt response.
bool aesCbcDecrypt (const CW_SecureSession &session, uint8_t *response, size_t responseLen, uint8_t *macValue, uint8_t *decryptedOutput=NULL, uint16_t *decryptedOutputLength=NULL)
 Verify MAC and decrypt an encrypted APDU response.
bool checkStatusWord (const uint8_t *response, uint16_t responseLength, uint8_t sw1Expected, uint8_t sw2Expected)
 Verify the SW1/SW2 status word at the end of an APDU response.

Private Member Functions

bool verifyEcdsaSha256 (const uint8_t *pubKey64, const uint8_t *message, uint16_t msgLen, const uint8_t *derSig, uint8_t derSigLen)

Static Private Member Functions

static bool parseDerSigToRaw (const uint8_t *der, uint8_t derLen, uint8_t *raw64)

Private Attributes

CW_NfcTransport_driver
 NFC transport for APDU exchange.
CW_Logger_logger
 Logging interface.
CW_CryptoProvider_crypto
 Crypto operations (AES, SHA, ECDH, RNG).
CW_Platform_platform
 Platform abstraction (sleep_ms).
uint8_t _lastNonce [CW_CERT_NONCE_SIZE]
 Nonce sent in the last getCardCertificate() call; checked in verifyCertificateChain().
uint16_t _cachedMfCertLen
 Non-zero when s_mfCertBuf holds a valid pre-fetched manufacturer certificate.

Detailed Description

Implements the Cryptnox secure channel protocol over NFC.

Handles all low-level APDU exchanges required to establish and use a secure session with the Cryptnox smart card:

  • Application selection (SELECT APDU)
  • Card certificate retrieval and ephemeral key extraction
  • ECDH-based session key derivation (OPEN SECURE CHANNEL + MUTUALLY AUTHENTICATE)
  • AES-CBC-MAC secure messaging (encrypt / decrypt / MAC verify)
  • Status word checking

CW_SecureChannel is composed inside CryptnoxWallet and is not intended to be used directly by application code.

Definition at line 64 of file CW_SecureChannel.h.

Constructor & Destructor Documentation

◆ CW_SecureChannel() [1/2]

CW_SecureChannel::CW_SecureChannel ( CW_NfcTransport & driver,
CW_Logger & logger,
CW_CryptoProvider & crypto,
CW_Platform & platform )

Construct a CW_SecureChannel.

Parameters
driverReference to the NFC transport.
loggerReference to the logging interface.
cryptoReference to the crypto provider.
platformReference to the platform abstraction (for sleep_ms).

Definition at line 87 of file CW_SecureChannel.cpp.

References _cachedMfCertLen, _crypto, _driver, _lastNonce, _logger, and _platform.

Referenced by CW_SecureChannel(), and operator=().

◆ CW_SecureChannel() [2/2]

CW_SecureChannel::CW_SecureChannel ( const CW_SecureChannel & )
delete

References CW_SecureChannel().

Member Function Documentation

◆ aesCbcDecrypt()

bool CW_SecureChannel::aesCbcDecrypt ( const CW_SecureSession & session,
uint8_t * response,
size_t responseLen,
uint8_t * macValue,
uint8_t * decryptedOutput = NULL,
uint16_t * decryptedOutputLength = NULL )

Verify MAC and decrypt an encrypted APDU response.

Internal helper called from aesCbcEncrypt — exposed for the fuzz harness. Verifies the response MAC against Kmac, then decrypts the payload with Kenc using the supplied IV (which is the MAC of the sent request, by protocol).

Parameters
[in,out]sessionSecure session.
[in]responseEncrypted response buffer (MAC || cipher || SW).
[in]responseLenResponse length.
[in]macValueMAC of the request — used as decrypt IV.
[out]decryptedOutputOptional plaintext output buffer.
[out]decryptedOutputLengthOptional plaintext output length.
Returns
true if MAC matched and decryption succeeded, false otherwise.
Warning
A false return indicates either tampering or a corrupted channel — the session must not be reused without renegotiation.

Definition at line 625 of file CW_SecureChannel.cpp.

References _crypto, _logger, AES_BLOCK_SIZE, CW_SecureSession::aesKey, F, HEX, CW_SecureSession::macKey, s_apduBuf, s_dataBuf, s_macBuf, CW_Utils::safe_memcpy(), CW_Utils::secure_compare(), and CW_Utils::secure_wipe().

Referenced by aesCbcEncrypt().

◆ aesCbcEncrypt()

bool CW_SecureChannel::aesCbcEncrypt ( CW_SecureSession & session,
const uint8_t apdu[],
uint16_t apduLength,
const uint8_t data[],
uint16_t dataLength,
uint8_t * decryptedOutput = NULL,
uint16_t * decryptedOutputLength = NULL )

AES-CBC encrypt + MAC, send APDU, and decrypt response.

Performs one secure messaging round-trip: pads and encrypts data with Kenc using the current IV; computes a CMAC over (header || cipher) with Kmac; sends the wrapped APDU; on the response, verifies the MAC and decrypts the payload. The new IV for the next call is taken from the last cipher block (rolling IV).

Parameters
[in,out]sessionSecure session (Kenc / Kmac / IV).
[in]apduAPDU header (CLA, INS, P1, P2).
[in]apduLengthHeader length (must be 4).
[in]dataPlaintext payload.
[in]dataLengthPlaintext length (≤ CW_USER_DATA_PAGE_SIZE).
[out]decryptedOutputOptional buffer for the decrypted response payload.
[out]decryptedOutputLengthOptional pointer to receive the decrypted payload length.
Returns
true if the APDU was sent and the response MAC verified + decrypted successfully; false on bad parameters, transport failure, MAC mismatch, or unexpected status word.
Precondition
session must be the output of a successful mutuallyAuthenticate call.
Warning
Mutates session.iv. On any failure the IV may be left in an undefined state — treat the session as broken and tear it down with CW_SecureSession::clear.
Reuses module-private static buffers (s_apduBuf, s_macBuf, s_dataBuf). Not safe to call concurrently from multiple tasks; serialise at the application level.

One secure-messaging round-trip is built in five stages, reusing module- private scratch buffers (s_apduBuf, s_macBuf, s_dataBuf) to keep the call-site stack frame small:

  1. Plaintext padding — ISO/IEC 9797-1 Method 2 (bit padding) is appended to data so the length is a multiple of the AES block size.
  2. Encryption — AES-256-CBC under Kenc with the current rolling IV.
  3. MAC computation — AES-CMAC over (APDU header || Lc || ciphertext) under Kmac. The MAC's last 8 bytes are prepended to the ciphertext in the outgoing APDU.
  4. Transport — the assembled APDU goes to the card; the response is structured as (MAC[8] || cipher || SW1 SW2).
  5. Response decryption — delegated to aesCbcDecrypt, which verifies the response MAC against Kmac (using the request MAC as the IV per protocol) before decrypting under Kenc.

IV update — on success, the last 16 bytes of the response ciphertext become the new session IV (rolling IV). On any failure path the IV is left in an undefined state, which is why the caller must treat a false return as a dead session.

Definition at line 501 of file CW_SecureChannel.cpp.

References _crypto, _driver, _logger, AES_BLOCK_SIZE, aesCbcDecrypt(), CW_SecureSession::aesKey, APDU_LC_LEN, checkStatusWord(), CW_SecureSession::clear(), CW_IV_SIZE, F, HEX, INPUT_BUFFER_LIMIT, CW_SecureSession::iv, MAC_APDU_LEN, CW_SecureSession::macKey, MAX_MAC_DATA_LEN, s_apduBuf, s_dataBuf, s_macBuf, CW_Utils::safe_memcpy(), CW_Utils::secure_wipe(), and SEND_APDU_MAX_LEN.

◆ begin()

bool CW_SecureChannel::begin ( )

Initialize the NFC transport module.

Returns
true if the module was successfully initialised, false otherwise.

Definition at line 100 of file CW_SecureChannel.cpp.

References _driver.

◆ checkStatusWord()

bool CW_SecureChannel::checkStatusWord ( const uint8_t * response,
uint16_t responseLength,
uint8_t sw1Expected,
uint8_t sw2Expected )

Verify the SW1/SW2 status word at the end of an APDU response.

Parameters
responseAPDU response buffer.
responseLengthResponse length.
sw1ExpectedExpected SW1 byte.
sw2ExpectedExpected SW2 byte.
Returns
true if last two bytes match expectations, false otherwise.

Definition at line 120 of file CW_SecureChannel.cpp.

References _logger, F, and HEX.

Referenced by aesCbcEncrypt(), getCardCertificate(), getManufacturerCertificate(), mutuallyAuthenticate(), openSecureChannel(), and selectApdu().

◆ extractCardEphemeralKey()

bool CW_SecureChannel::extractCardEphemeralKey ( const uint8_t * cardCertificate,
uint8_t * cardEphemeralPubKey,
uint8_t * fullEphemeralPubKey65 = NULL )

Extract the card's ephemeral EC P-256 public key from a certificate.

Parameters
[in]cardCertificateRaw certificate bytes.
[out]cardEphemeralPubKey64-byte key (X||Y, no 0x04 prefix) for ECDH.
[out]fullEphemeralPubKey65Optional 65-byte key including 0x04 prefix.
Returns
true on success, false otherwise.

Definition at line 232 of file CW_SecureChannel.cpp.

◆ getCardCertificate()

bool CW_SecureChannel::getCardCertificate ( uint8_t * cardCertificate,
uint8_t & cardCertificateLength )

Retrieve the card's ephemeral public key via GET CARD CERTIFICATE.

Sends a random challenge nonce to the card and stores it internally. The nonce echo check is performed inside verifyCertificateChain() to ensure replay protection is coupled with signature verification.

Parameters
[out]cardCertificateBuffer to receive the raw certificate bytes.
[out]cardCertificateLengthActual certificate length (bytes).
Returns
true on success, false otherwise.

Definition at line 184 of file CW_SecureChannel.cpp.

References _crypto, _driver, _lastNonce, _logger, checkStatusWord(), F, GETCARDCERTIFICATE_IN_BYTES, RANDOM_BYTES, RESPONSE_GETCARDCERTIFICATE_IN_BYTES, RESPONSE_STATUS_WORDS_IN_BYTES, and CW_Utils::safe_memcpy().

◆ getManufacturerCertificate()

bool CW_SecureChannel::getManufacturerCertificate ( uint8_t * cert,
uint16_t & certLen )

Retrieve the manufacturer certificate stored in card flash.

Parameters
[out]certBuffer to receive the raw DER certificate bytes.
[out]certLenActual certificate length written.
Returns
true on success, false if APDU fails or buffer too small.

Definition at line 1098 of file CW_SecureChannel.cpp.

References _driver, _logger, checkStatusWord(), CW_MANUF_CERT_MAX_BYTES, F, RESPONSE_GETMANUFACTURERCERT_PAGE_IN_BYTES, RESPONSE_STATUS_WORDS_IN_BYTES, and CW_Utils::safe_memcpy().

Referenced by preFetchManufacturerCert(), and verifyCertificateChain().

◆ inListPassiveTarget()

bool CW_SecureChannel::inListPassiveTarget ( )

Detect a passive NFC target (ISO-DEP card).

Returns
true if a card was found, false otherwise.

Definition at line 104 of file CW_SecureChannel.cpp.

References _driver.

◆ mutuallyAuthenticate()

bool CW_SecureChannel::mutuallyAuthenticate ( CW_SecureSession & session,
const uint8_t * salt,
uint8_t * clientPublicKey,
const uint8_t * clientPrivateKey,
CW_Curve sessionCurve,
const uint8_t * cardEphemeralPubKey )

Perform ECDH derivation and MUTUALLY AUTHENTICATE with the card.

Final step of the secure channel handshake:

  1. ECDH shared secret = clientPrivateKey · cardEphemeralPubKey
  2. (Kenc || Kmac || IV) ← SHA-512(salt || pairingKey || sharedSecret)
  3. Encrypts a 16-byte random challenge with the new Kenc and sends it inside the MUTUALLY AUTHENTICATE APDU
  4. Verifies the card returns the same plaintext when re-encrypting its own counter — this proves the card knows Kenc
Parameters
[out]sessionSecure session populated with derived keys + initial IV.
[in]salt32-byte salt from openSecureChannel.
[in]clientPublicKey64-byte client public key.
[in]clientPrivateKey32-byte client private key.
[in]sessionCurveECC curve.
[in]cardEphemeralPubKey64-byte card ephemeral public key.
Returns
true on success, false if ECDH failed, the card's challenge response did not match, or any APDU exchange failed.
Precondition
openSecureChannel must have been called and returned true.
Postcondition
On true: session has Kenc, Kmac, and rolling IV ready for aesCbcEncrypt. On false: session is left untouched and must not be used.
Warning
All ephemeral key material in the caller's stack (clientPrivateKey, salt) must be wiped after this call.

Cryptographic flow:

  1. Compute the ECDH shared secret S = ECDH(clientPrivateKey, cardEphemeralPubKey) on the negotiated curve.
  2. Derive 80 bytes of keying material via SHA-512 over (salt || S || pairingDataHash) and split into:
    • Kenc[32]: AES-256 session encryption key
    • Kmac[32]: AES-256 session MAC key
    • IV[16] : initial rolling IV
  3. Send MUTUALLY AUTHENTICATE with a random 16-byte challenge encrypted under Kenc / IV. The card must answer with the same 16 bytes re-encrypted with the new IV — a verification that fails fast on any key-derivation mismatch.
  4. On success, populate session and wipe sharedSecret from the stack.

Failure modes that cause an early-exit with a wiped session:

  • ECDH returned zero or invalid (curve mismatch)
  • APDU transport failure
  • Card challenge response mismatch (active attacker or wrong card)

Definition at line 334 of file CW_SecureChannel.cpp.

References _crypto, _driver, _logger, AES_BLOCK_SIZE, CW_SecureSession::aesKey, APDU_HEADER_LEN, APDU_LC_LEN, checkStatusWord(), CW_SecureSession::clear(), COMMON_PAIRING_DATA, CW_AESKEY_SIZE, CW_IV_SIZE, CW_MACKEY_SIZE, F, CW_SecureSession::iv, CW_SecureSession::macKey, REQUEST_MUTUALLYAUTHENTICATE_IN_BYTES, RESPONSE_MUTUALLYAUTHENTICATE_IN_BYTES, CW_Utils::safe_memcpy(), and CW_Utils::secure_wipe().

◆ openSecureChannel()

bool CW_SecureChannel::openSecureChannel ( uint8_t * salt,
uint8_t * clientPublicKey,
uint8_t * clientPrivateKey,
CW_Curve sessionCurve )

Send OPEN SECURE CHANNEL and retrieve the session salt.

Generates a client EC key pair via the crypto provider and sends the public key to the card; the card responds with a 32-byte salt that later feeds into Kenc / Kmac derivation in mutuallyAuthenticate.

Parameters
[out]salt32-byte session salt returned by the card.
[out]clientPublicKey64-byte freshly generated client public key.
[out]clientPrivateKey32-byte freshly generated client private key.
[in]sessionCurveECC curve for key generation (secp256r1).
Returns
true on success, false otherwise.
Precondition
selectApdu must have been called successfully.
Warning
clientPrivateKey is sensitive — the caller MUST wipe it via CW_Utils::secure_wipe on every exit path.

Definition at line 265 of file CW_SecureChannel.cpp.

References _crypto, _driver, _logger, checkStatusWord(), CLIENT_PUBLIC_KEY_SIZE, F, OPENSECURECHANNEL_SALT_IN_BYTES, RESPONSE_OPENSECURECHANNEL_IN_BYTES, and CW_Utils::safe_memcpy().

◆ operator=()

CW_SecureChannel & CW_SecureChannel::operator= ( const CW_SecureChannel & )
delete

References CW_SecureChannel().

◆ parseDerSigToRaw()

bool CW_SecureChannel::parseDerSigToRaw ( const uint8_t * der,
uint8_t derLen,
uint8_t * raw64 )
staticprivate

Definition at line 1018 of file CW_SecureChannel.cpp.

References CW_Utils::safe_memcpy().

Referenced by verifyEcdsaSha256().

◆ preFetchManufacturerCert()

bool CW_SecureChannel::preFetchManufacturerCert ( )

Fetch and cache the manufacturer certificate before getCardCertificate().

The Cryptnox card state machine advances after GET_CARD_CERTIFICATE (INS=F8) and will not respond to GET_MANUFACTURER_CERTIFICATE (INS=F7) after that point. Call this method immediately after selectApdu() and before getCardCertificate() so that verifyCertificateChain() can use the cached copy without an APDU.

Returns
true if the certificate was fetched and cached, false otherwise.

Definition at line 1194 of file CW_SecureChannel.cpp.

References _cachedMfCertLen, getManufacturerCertificate(), and s_mfCertBuf.

◆ printFirmwareVersion()

bool CW_SecureChannel::printFirmwareVersion ( )

Print the NFC reader firmware version to the logger.

Returns
true on success, false otherwise.

Definition at line 112 of file CW_SecureChannel.cpp.

References _driver.

◆ resetReader()

void CW_SecureChannel::resetReader ( )

Reset the NFC reader hardware.

Definition at line 108 of file CW_SecureChannel.cpp.

References _driver.

◆ selectApdu()

bool CW_SecureChannel::selectApdu ( )

Send the SELECT APDU to activate the Cryptnox application.

Returns
true on success, false otherwise.

Definition at line 155 of file CW_SecureChannel.cpp.

References _driver, _logger, checkStatusWord(), F, and RESPONSE_SELECT_IN_BYTES.

◆ verifyCertificateChain()

uint8_t CW_SecureChannel::verifyCertificateChain ( const uint8_t * cardCert,
uint8_t cardCertLen )

Verify the full card certificate chain against the trusted CA.

Walks the cached manufacturer certificate (fetched earlier by preFetchManufacturerCert), verifies its ECDSA signature against each entry in CW_TRUSTED_CA_KEYS, then verifies the card's ephemeral certificate against the manufacturer public key. Also checks that the challenge nonce sent in getCardCertificate was echoed back inside the card certificate.

Parameters
[in]cardCertRaw card certificate bytes (typically 146 bytes).
[in]cardCertLenLength of cardCert.
Returns
One of the CW_CERT_* result codes:
Return values
CW_CERT_OKChain verified end-to-end.
CW_CERT_FORMAT_ERRORMalformed certificate / unexpected TLV.
CW_CERT_NONCE_MISMATCHCard did not echo the challenge nonce.
CW_CERT_CARD_SIG_INVALIDCard cert ECDSA signature failed verification.
CW_CERT_MANUF_SIG_INVALIDManufacturer cert signature does not match any trusted CA key.
CW_CERT_KEY_NOT_FOUNDDevice public-key OID not found in the certificate.
Precondition
preFetchManufacturerCert must have been called and returned true (the manufacturer certificate is cached internally and not re-fetchable after getCardCertificate).
getCardCertificate must have been called so the challenge nonce is recorded internally.

Two-step ECDSA chain walk against the pinned trusted CAs in CW_TRUSTED_CA_KEYS (currently a single secp256r1 key, CW_CA_DLT_PUBKEY):

  1. Manufacturer certificate — the cached DER blob fetched by preFetchManufacturerCert is parsed to extract its EC public key and its ECDSA signature. The signature is verified against every entry in the trusted-CA table; the first match wins. The extracted manufacturer public key becomes the trusted issuer for step 2.
  2. Card certificate — cardCert is parsed for the device's ephemeral public key, the manufacturer ECDSA signature over that key, and the echoed challenge nonce. The nonce is compared (constant-time) against the value stored by getCardCertificate; mismatch immediately returns CW_CERT_NONCE_MISMATCH to defeat replay. The signature is then verified against the manufacturer public key from step 1.

Both signatures are SHA-256-then-ECDSA over the relevant TBS bytes. Any TLV parsing error short-circuits with CW_CERT_FORMAT_ERROR rather than touching the verifier — DER parsing is the largest attack surface here and is independently fuzzed (see fuzz/fuzz_der.cpp).

Definition at line 1227 of file CW_SecureChannel.cpp.

References _cachedMfCertLen, _lastNonce, _logger, CW_CERT_CARD_SIG_INVALID, CW_CERT_FORMAT_ERROR, CW_CERT_KEY_NOT_FOUND, CW_CERT_MANUF_SIG_INVALID, CW_CERT_NONCE_MISMATCH, CW_CERT_NONCE_SIZE, CW_CERT_OK, CW_TRUSTED_CA_COUNT, CW_TRUSTED_CA_KEYS, derWalkMfCert(), F, getManufacturerCertificate(), s_mfCertBuf, CW_Utils::secure_compare(), CW_Utils::secure_wipe(), and verifyEcdsaSha256().

◆ verifyEcdsaSha256()

bool CW_SecureChannel::verifyEcdsaSha256 ( const uint8_t * pubKey64,
const uint8_t * message,
uint16_t msgLen,
const uint8_t * derSig,
uint8_t derSigLen )
private

Definition at line 1082 of file CW_SecureChannel.cpp.

References _crypto, CW_CURVE_SECP256R1, and parseDerSigToRaw().

Referenced by verifyCertificateChain().

Member Data Documentation

◆ _cachedMfCertLen

uint16_t CW_SecureChannel::_cachedMfCertLen
private

Non-zero when s_mfCertBuf holds a valid pre-fetched manufacturer certificate.

Definition at line 322 of file CW_SecureChannel.h.

Referenced by CW_SecureChannel(), preFetchManufacturerCert(), and verifyCertificateChain().

◆ _crypto

CW_CryptoProvider& CW_SecureChannel::_crypto
private

Crypto operations (AES, SHA, ECDH, RNG).

Definition at line 315 of file CW_SecureChannel.h.

Referenced by aesCbcDecrypt(), aesCbcEncrypt(), CW_SecureChannel(), getCardCertificate(), mutuallyAuthenticate(), openSecureChannel(), and verifyEcdsaSha256().

◆ _driver

◆ _lastNonce

uint8_t CW_SecureChannel::_lastNonce[CW_CERT_NONCE_SIZE]
private

Nonce sent in the last getCardCertificate() call; checked in verifyCertificateChain().

Definition at line 319 of file CW_SecureChannel.h.

Referenced by CW_SecureChannel(), getCardCertificate(), and verifyCertificateChain().

◆ _logger

◆ _platform

CW_Platform& CW_SecureChannel::_platform
private

Platform abstraction (sleep_ms).

Definition at line 316 of file CW_SecureChannel.h.

Referenced by CW_SecureChannel().


The documentation for this class was generated from the following files: