srtp操作还是比较简单的
#srtp sesssion创建
SrtpSession::SrtpSession(Type type, Profile profile, uint8_t* key, size_t keyLen)
{
MS_TRACE();
srtp_policy_t policy; // NOLINT(cppcoreguidelines-pro-type-member-init)
// Set all policy fields to 0.
std::memset(&policy, 0, sizeof(srtp_policy_t));
switch (profile)
{
case Profile::AES_CM_128_HMAC_SHA1_80:
{
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
break;
}
case Profile::AES_CM_128_HMAC_SHA1_32:
{
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
// NOTE: Must be 80 for RTCP.
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
break;
}
case Profile::AEAD_AES_256_GCM:
{
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtcp);
break;
}
case Profile::AEAD_AES_128_GCM:
{
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp);
break;
}
default:
{
MS_ABORT("unknown SRTP profile");
}
}
MS_ASSERT(
(int)keyLen == policy.rtp.cipher_key_len,
"given keyLen does not match policy.rtp.cipher_keyLen");
switch (type)
{
case Type::INBOUND:
policy.ssrc.type = ssrc_any_inbound;
break;
case Type::OUTBOUND:
policy.ssrc.type = ssrc_any_outbound;
break;
}
policy.ssrc.value = 0;
policy.key = key;
// Required for sending RTP retransmission without RTX.
policy.allow_repeat_tx = 1;
policy.window_size = 1024;
policy.next = nullptr;
// Set the SRTP session.
srtp_err_status_t err = srtp_create(&this->session, &policy);
if (DepLibSRTP::IsError(err))
MS_THROW_ERROR("srtp_create() failed: %s", DepLibSRTP::GetErrorString(err));
}
#加解密rtp
bool SrtpSession::EncryptRtp(const uint8_t** data, size_t* len)
{
MS_TRACE();
// Ensure that the resulting SRTP packet fits into the encrypt buffer.
if (*len + SRTP_MAX_TRAILER_LEN > EncryptBufferSize)
{
MS_WARN_TAG(srtp, "cannot encrypt RTP packet, size too big (%zu bytes)", *len);
return false;
}
std::memcpy(EncryptBuffer, *data, *len);
srtp_err_status_t err =
srtp_protect(this->session, (void*)EncryptBuffer, reinterpret_cast<int*>(len));
if (DepLibSRTP::IsError(err))
{
MS_WARN_TAG(srtp, "srtp_protect() failed: %s", DepLibSRTP::GetErrorString(err));
return false;
}
// Update the given data pointer.
*data = (const uint8_t*)EncryptBuffer;
return true;
}
bool SrtpSession::DecryptSrtp(const uint8_t* data, size_t* len)
{
MS_TRACE();
srtp_err_status_t err = srtp_unprotect(this->session, (void*)data, reinterpret_cast<int*>(len));
if (DepLibSRTP::IsError(err))
{
MS_DEBUG_TAG(srtp, "srtp_unprotect() failed: %s", DepLibSRTP::GetErrorString(err));
return false;
}
return true;
}
#加解密rtcp
bool SrtpSession::EncryptRtcp(const uint8_t** data, size_t* len)
{
MS_TRACE();
// Ensure that the resulting SRTCP packet fits into the encrypt buffer.
if (*len + SRTP_MAX_TRAILER_LEN > EncryptBufferSize)
{
MS_WARN_TAG(srtp, "cannot encrypt RTCP packet, size too big (%zu bytes)", *len);
return false;
}
std::memcpy(EncryptBuffer, *data, *len);
srtp_err_status_t err =
srtp_protect_rtcp(this->session, (void*)EncryptBuffer, reinterpret_cast<int*>(len));
if (DepLibSRTP::IsError(err))
{
MS_WARN_TAG(srtp, "srtp_protect_rtcp() failed: %s", DepLibSRTP::GetErrorString(err));
return false;
}
// Update the given data pointer.
*data = (const uint8_t*)EncryptBuffer;
return true;
}
bool SrtpSession::DecryptSrtcp(const uint8_t* data, size_t* len)
{
MS_TRACE();
srtp_err_status_t err =
srtp_unprotect_rtcp(this->session, (void*)data, reinterpret_cast<int*>(len));
if (DepLibSRTP::IsError(err))
{
MS_DEBUG_TAG(srtp, "srtp_unprotect_rtcp() failed: %s", DepLibSRTP::GetErrorString(err));
return false;
}
return true;
}