Add support for SRTP NULL cipher

This commit is contained in:
Aaro Altonen 2020-07-30 11:47:11 +03:00
parent 61f7ef0416
commit 77fc7df078
4 changed files with 31 additions and 14 deletions

View File

@ -112,7 +112,7 @@ namespace uvg_rtp {
* Return RTP_OK if SRTP setup was successful
* Return RTP_INVALID_VALUE if "zrtp" is nullptr
* Return RTP_MEMORY allocation failed */
rtp_error_t init_zrtp(int type, uvg_rtp::rtp *rtp, uvg_rtp::zrtp *zrtp);
rtp_error_t init_zrtp(int type, bool use_null_cipher, uvg_rtp::rtp *rtp, uvg_rtp::zrtp *zrtp);
/* Setup Secure RTP/RTCP connection using user-managed keys
*
@ -122,7 +122,7 @@ namespace uvg_rtp {
* Return RTP_OK if SRTP setup was successful
* Return RTP_INVALID_VALUE if "key" or "salt" is nullptr
* Return RTP_MEMORY allocation failed */
rtp_error_t init_user(int type, uint8_t *key, uint8_t *salt);
rtp_error_t init_user(int type, bool use_null_cipher, uint8_t *key, uint8_t *salt);
/* Encrypt the payload of "frame" using the private session key
*
@ -168,10 +168,14 @@ namespace uvg_rtp {
rtp_error_t __encrypt(uint32_t ssrc, uint16_t seq, uint8_t *buffer, size_t len);
/* Internal init method that initialize the SRTP context using values in key_ctx_.master */
rtp_error_t __init(int type);
rtp_error_t __init(int type, bool use_null_cipher);
#endif
srtp_key_ctx_t key_ctx_;
srtp_ctx_t srtp_ctx_;
/* If NULL cipher is enabled, it means that RTP packets are not
* encrypted but other security mechanisms described in RFC 3711 may be used */
bool use_null_cipher_;
};
};

View File

@ -178,7 +178,10 @@ enum RTP_CTX_ENABLE_FLAGS {
* Mutually exclusive with RCE_UNIDIR_SENDER */
RCE_UNIDIR_RECEIVER = 1 << 11,
RCE_LAST = 1 << 12,
/* Disable RTP payload encryption */
RCE_SRTP_NULL_CIPHER = 1 << 12,
RCE_LAST = 1 << 13,
};
/* These options are given to configuration() */

View File

@ -10,8 +10,9 @@
#define RECV_ONLY_FLAGS (RCE_UNIDIRECTIONAL | RCE_UNIDIR_RECEIVER)
#define SEND_ONLY_FLAGS (RCE_UNIDIRECTIONAL | RCE_UNIDIR_SENDER)
#define RECV_ONLY(flags) ((flags & RECV_ONLY_FLAGS) == RECV_ONLY_FLAGS)
#define SEND_ONLY(flags) ((flags & SEND_ONLY_FLAGS) == SEND_ONLY_FLAGS)
#define RECV_ONLY(flags) ((flags & RECV_ONLY_FLAGS) == RECV_ONLY_FLAGS)
#define SEND_ONLY(flags) ((flags & SEND_ONLY_FLAGS) == SEND_ONLY_FLAGS)
#define NULL_CHIPER(flags) ((flags & RCE_SRTP_USE_NULL_CIPHER) == RCE_SRTP_USE_NULL_CIPHER)
uvg_rtp::media_stream::media_stream(std::string addr, int src_port, int dst_port, rtp_format_t fmt, int flags):
srtp_(nullptr),
@ -173,7 +174,7 @@ rtp_error_t uvg_rtp::media_stream::init(uvg_rtp::zrtp *zrtp)
if ((srtp_ = new uvg_rtp::srtp()) == nullptr)
return RTP_MEMORY_ERROR;
if ((ret = srtp_->init_zrtp(SRTP, rtp_, zrtp)) != RTP_OK) {
if ((ret = srtp_->init_zrtp(SRTP, NULL_CHIPER(ctx_config_.flags), rtp_, zrtp)) != RTP_OK) {
LOG_WARN("Failed to initialize SRTP for media stream!");
return ret;
}
@ -213,7 +214,7 @@ rtp_error_t uvg_rtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt)
if ((srtp_ = new uvg_rtp::srtp()) == nullptr)
return RTP_MEMORY_ERROR;
if ((ret = srtp_->init_user(SRTP, key, salt)) != RTP_OK) {
if ((ret = srtp_->init_user(SRTP, NULL_CHIPER(ctx_config_.flags), key, salt)) != RTP_OK) {
LOG_WARN("Failed to initialize SRTP for media stream!");
return ret;
}

View File

@ -9,7 +9,8 @@
#endif
uvg_rtp::srtp::srtp():
srtp_ctx_()
srtp_ctx_(),
use_null_cipher_(false)
{
}
@ -53,7 +54,7 @@ rtp_error_t uvg_rtp::srtp::create_iv(uint8_t *out, uint32_t ssrc, uint64_t index
return RTP_OK;
}
rtp_error_t uvg_rtp::srtp::__init(int type)
rtp_error_t uvg_rtp::srtp::__init(int type, bool use_null_cipher)
{
srtp_ctx_.roc = 0;
srtp_ctx_.type = type;
@ -74,6 +75,8 @@ rtp_error_t uvg_rtp::srtp::__init(int type)
srtp_ctx_.s_l = 0;
srtp_ctx_.replay = nullptr;
use_null_cipher_ = use_null_cipher;
/* Local aka encryption keys */
(void)derive_key(
SRTP_ENCRYPTION,
@ -123,7 +126,7 @@ rtp_error_t uvg_rtp::srtp::__init(int type)
return RTP_OK;
}
rtp_error_t uvg_rtp::srtp::init_zrtp(int type, uvg_rtp::rtp *rtp, uvg_rtp::zrtp *zrtp)
rtp_error_t uvg_rtp::srtp::init_zrtp(int type, bool use_null_cipher, uvg_rtp::rtp *rtp, uvg_rtp::zrtp *zrtp)
{
(void)rtp;
@ -148,10 +151,10 @@ rtp_error_t uvg_rtp::srtp::init_zrtp(int type, uvg_rtp::rtp *rtp, uvg_rtp::zrtp
return ret;
}
return __init(type);
return __init(type, use_null_cipher);
}
rtp_error_t uvg_rtp::srtp::init_user(int type, uint8_t *key, uint8_t *salt)
rtp_error_t uvg_rtp::srtp::init_user(int type, bool use_null_cipher, uint8_t *key, uint8_t *salt)
{
if (!key || !salt)
return RTP_INVALID_VALUE;
@ -161,11 +164,14 @@ rtp_error_t uvg_rtp::srtp::init_user(int type, uint8_t *key, uint8_t *salt)
memcpy(key_ctx_.master.local_salt, salt, SALT_LENGTH);
memcpy(key_ctx_.master.remote_salt, salt, SALT_LENGTH);
return __init(type);
return __init(type, use_null_cipher);
}
rtp_error_t uvg_rtp::srtp::__encrypt(uint32_t ssrc, uint16_t seq, uint8_t *buffer, size_t len)
{
if (use_null_cipher_)
return RTP_OK;
uint8_t iv[16] = { 0 };
uint64_t index = (((uint64_t)srtp_ctx_.roc) << 16) + seq;
@ -199,6 +205,9 @@ rtp_error_t uvg_rtp::srtp::encrypt(std::vector<std::pair<size_t, uint8_t *>>& bu
rtp_error_t uvg_rtp::srtp::decrypt(uint8_t *buffer, size_t len)
{
if (use_null_cipher_)
return RTP_OK;
uint8_t iv[16] = { 0 };
auto hdr = (uvg_rtp::frame::rtp_header *)buffer;
uint16_t seq = ntohs(hdr->seq);