Skip to content

Commit

Permalink
[API] Crypto mode 'auto' implemented for listener.
Browse files Browse the repository at this point in the history
Caller or rendezvous still falls back to AES-CTR.
  • Loading branch information
maxsharabayko committed Dec 8, 2022
1 parent ba67d36 commit adc60c5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/API/API-socket-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ The encryption mode to be used if the [`SRTO_PASSPHRASE`](#SRTO_PASSPHRASE) is s

Crypto modes:

- `0`: auto-select during handshake negotiation (to be implemented; currently similar to AES-CTR).
- `0`: SRT listener accepts any mode from the caller. SRT Caller or SRT Rendezvous use AES-CTR (1).
- `1`: regular AES-CTR (without message integrity authentication).
- `2`: AES-GCM mode with message integrity authentication (AEAD).

Expand Down
5 changes: 4 additions & 1 deletion srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,10 @@ void srt::CUDT::getOpt(SRT_SOCKOPT optName, void *optval, int &optlen)
break;

case SRTO_CRYPTOMODE:
*(int32_t*)optval = m_config.iCryptoMode;
if (m_pCryptoControl)
*(int32_t*)optval = m_pCryptoControl->getCryptoMode();
else
*(int32_t*)optval = m_config.iCryptoMode;
optlen = sizeof(int32_t);
break;

Expand Down
25 changes: 19 additions & 6 deletions srtcore/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ int srt::CCryptoControl::processSrtMsg_KMREQ(
bool wasb4 SRT_ATR_UNUSED = false;
size_t sek_len = 0;

const bool bUseGCM =
(m_iCryptoMode == CSrtConfig::CIPHER_MODE_AUTO && kmdata[HCRYPT_MSG_KM_OFS_CIPHER] == HCRYPT_CIPHER_AES_GCM) ||
(m_iCryptoMode == CSrtConfig::CIPHER_MODE_AES_GCM);

// What we have to do:
// If encryption is on (we know that by having m_KmSecret nonempty), create
// the crypto context (if bidirectional, create for both sending and receiving).
Expand Down Expand Up @@ -208,13 +212,16 @@ int srt::CCryptoControl::processSrtMsg_KMREQ(
}
wasb4 = m_hRcvCrypto;

if (!createCryptoCtx((m_hRcvCrypto), m_iRcvKmKeyLen, HAICRYPT_CRYPTO_DIR_RX, m_bUseGCM))
if (!createCryptoCtx((m_hRcvCrypto), m_iRcvKmKeyLen, HAICRYPT_CRYPTO_DIR_RX, bUseGCM))
{
LOGC(cnlog.Error, log << "processSrtMsg_KMREQ: Can't create RCV CRYPTO CTX - must reject...");
m_RcvKmState = SRT_KM_S_NOSECRET;
KMREQ_RESULT_REJECTION();
}

// Deduce resulting mode.
m_iCryptoMode = bUseGCM ? CSrtConfig::CIPHER_MODE_AES_GCM : CSrtConfig::CIPHER_MODE_AES_CTR;

if (!wasb4)
{
HLOGC(cnlog.Debug, log << "processSrtMsg_KMREQ: created RX ENC with KeyLen=" << m_iRcvKmKeyLen);
Expand Down Expand Up @@ -573,7 +580,7 @@ srt::CCryptoControl::CCryptoControl(SRTSOCKET id)
, m_RcvKmState(SRT_KM_S_UNSECURED)
, m_KmRefreshRatePkt(0)
, m_KmPreAnnouncePkt(0)
, m_bUseGCM(false)
, m_iCryptoMode(CSrtConfig::CIPHER_MODE_AUTO)
, m_bErrorReported(false)
{
m_KmSecret.len = 0;
Expand All @@ -600,10 +607,14 @@ bool srt::CCryptoControl::init(HandshakeSide side, const CSrtConfig& cfg, bool b

// Set UNSECURED state as default
m_RcvKmState = SRT_KM_S_UNSECURED;
m_bUseGCM = cfg.iCryptoMode == CSrtConfig::CIPHER_MODE_AES_GCM;
m_iCryptoMode = cfg.iCryptoMode;

#ifdef SRT_ENABLE_ENCRYPTION
if (m_bUseGCM && !isAESGCMSupported())
if (!cfg.bTSBPD && m_iCryptoMode == CSrtConfig::CIPHER_MODE_AUTO)
m_iCryptoMode = CSrtConfig::CIPHER_MODE_AES_CTR;
const bool bUseGCM = m_iCryptoMode == CSrtConfig::CIPHER_MODE_AES_GCM;

if (bUseGCM && !isAESGCMSupported())
{
LOGC(cnlog.Warn, log << "CCryptoControl: AES GCM is not supported by the crypto service provider.");
return false;
Expand All @@ -616,7 +627,7 @@ bool srt::CCryptoControl::init(HandshakeSide side, const CSrtConfig& cfg, bool b
m_KmPreAnnouncePkt = cfg.uKmPreAnnouncePkt;
m_KmRefreshRatePkt = cfg.uKmRefreshRatePkt;

if ( side == HSD_INITIATOR )
if (side == HSD_INITIATOR)
{
if (hasPassphrase())
{
Expand All @@ -627,7 +638,7 @@ bool srt::CCryptoControl::init(HandshakeSide side, const CSrtConfig& cfg, bool b
m_iSndKmKeyLen = 16;
}

bool ok = createCryptoCtx((m_hSndCrypto), m_iSndKmKeyLen, HAICRYPT_CRYPTO_DIR_TX, m_bUseGCM);
bool ok = createCryptoCtx((m_hSndCrypto), m_iSndKmKeyLen, HAICRYPT_CRYPTO_DIR_TX, bUseGCM);
HLOGC(cnlog.Debug, log << "CCryptoControl::init: creating SND crypto context: " << ok);

if (ok && bidirectional)
Expand All @@ -652,6 +663,8 @@ bool srt::CCryptoControl::init(HandshakeSide side, const CSrtConfig& cfg, bool b
NULL, // Do not send the key (the KM msg will be attached to the HSv5 handshake)
bidirectional // replicate the key to the receiver context, if bidirectional
);

m_iCryptoMode = bUseGCM ? CSrtConfig::CIPHER_MODE_AES_GCM : CSrtConfig::CIPHER_MODE_AES_CTR;
#else
// This error would be a consequence of setting the passphrase, while encryption
// is turned off at compile time. Setting the password itself should be not allowed
Expand Down
7 changes: 6 additions & 1 deletion srtcore/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class CCryptoControl
// putting the whole HaiCrypt_Cfg object here.
int m_KmRefreshRatePkt;
int m_KmPreAnnouncePkt;
bool m_bUseGCM; // Use AES GCM crypto mode.
int m_iCryptoMode;

HaiCrypt_Secret m_KmSecret; //Key material shared secret
// Sender
Expand Down Expand Up @@ -111,6 +111,11 @@ class CCryptoControl
return m_KmSecret.len > 0;
}

int getCryptoMode() const
{
return m_iCryptoMode;
}

/// Regenerate cryptographic key material if needed.
/// @param[in] sock If not null, the socket will be used to send the KM message to the peer (e.g. KM refresh).
/// @param[in] bidirectional If true, the key material will be regenerated for both directions (receiver and sender).
Expand Down

0 comments on commit adc60c5

Please sign in to comment.