70#if HAVE_SRTP_VERSION > 1
71# include <srtp2/srtp.h>
73# include <openssl/rand.h>
75# include <srtp/srtp.h>
77# include <openssl/rand.h>
79# include <srtp/crypto_kernel.h>
153 return "nothing to report";
155 return "unspecified failure";
157 return "unsupported parameter";
159 return "couldn't allocate memory";
161 return "couldn't deallocate properly";
163 return "couldn't initialize";
165 return "can't process as much data as requested";
167 return "authentication failure";
169 return "cipher failure";
171 return "replay check failed (bad index)";
173 return "replay check failed (index too old)";
175 return "algorithm failed test routine";
177 return "unsupported operation";
179 return "no appropriate context found";
181 return "unable to perform desired validation";
183 return "can't use key any more";
193 return policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type;
200 return one->
sp.ssrc.type == two->sp.ssrc.type && one->
sp.ssrc.value == two->sp.ssrc.value;
207 .ssrc.type = policy->ssrc.type,
208 .ssrc.value = policy->ssrc.value,
241 switch (
data->event) {
242 case event_ssrc_collision:
245 case event_key_soft_limit:
248 case event_key_hard_limit:
251 case event_packet_index_limit:
252 ast_debug(1,
"event_packet_index_limit\n");
258 unsigned long ssrc,
int inbound)
261 policy->
sp.ssrc.type = ssrc_specific;
262 policy->
sp.ssrc.value = ssrc;
264 policy->
sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
272 if (policy->
sp.key) {
291 ao2_t_ref(policy, -1,
"Destroying policy");
305#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
314#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
323#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
332#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
355 size_t size = key_len + salt_len;
356 unsigned char *master_key;
358 if (policy->
sp.key) {
367 memcpy(master_key, key, key_len);
368 memcpy(master_key + key_len, salt, salt_len);
370 policy->
sp.key = master_key;
378 return RAND_bytes(key,
len) > 0 ? 0: -1;
399 int rtcp = (flags & 0x01) >> 0;
400 int retry = (flags & 0x02) >> 1;
406 ast_log(
LOG_ERROR,
"SRTP unprotect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
411 for (i = 0; i < 2; i++) {
438 ast_debug(5,
"SRTP destroy before re-create\n");
450 int res_srtp_create = srtp_create(&srtp->
session, &policy->
sp);
452 ast_debug(5,
"SRTP re-created with first policy\n");
453 ao2_t_ref(policy, -1,
"Unreffing first policy for re-creating srtp session");
456 if (policies_count > 1) {
457 ast_debug(5,
"Add all the other %d policies\n",
460 srtp_add_stream(srtp->
session, &policy->
sp);
461 ao2_t_ref(policy, -1,
"Unreffing n-th policy for re-creating srtp session");
474 ao2_t_ref(policy, -1,
"Unreffing first policy after srtp_create failed");
496 ast_verb(2,
"SRTCP unprotect failed on SSRC %u because of %s\n",
499 if ((srtp->
warned >= 10) && !((srtp->
warned - 10) % 150)) {
500 ast_verb(2,
"SRTP unprotect failed on SSRC %u because of %s %d\n",
517 unsigned char *localbuf;
520 ast_log(
LOG_ERROR,
"SRTP protect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
525 if ((*
len + SRTP_MAX_TRAILER_LEN) >
sizeof(srtp->
buf)) {
531 memcpy(localbuf, *
buf, *
len);
558 ast_log(
LOG_ERROR,
"Failed to create srtp session on rtp instance (%p) - %s\n",
566 ao2_t_link((*srtp)->policies, policy,
"Created initial policy");
582 "- keeping old\n", *srtp,
rtp);
607 if (policy->
sp.ssrc.type != ssrc_specific) {
620 ast_debug(3,
"Adding new policy for %s %u\n",
621 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
622 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
625 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
626 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
638 struct srtp_policy_t sp = {
639 .ssrc.type = ssrc_specific,
640 .ssrc.value = from_ssrc,
648 match->sp.ssrc.value = to_ssrc;
651 }
else if ((
status = srtp_remove_stream(srtp->
session, from_ssrc))) {
739 if ((taglen & 0x007f) == 8) {
741 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
742 }
else if ((taglen & 0x007f) == 16) {
745 }
else if ((taglen & 0x0300) && !(taglen & 0x0080)) {
747 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
750 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
805 if (
set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
815 ast_debug(1 ,
"SRTP policy activated\n");
835 char *key_params =
NULL;
836 char *key_param =
NULL;
837 char *session_params =
NULL;
838 char *key_salt =
NULL;
839 char *lifetime =
NULL;
842 int key_len_from_sdp;
843 int key_len_expected;
846 unsigned char remote_key[SRTP_MAX_KEY_LEN];
848 double sdes_lifetime;
859 if (!tag || !suite) {
865 if (sscanf(tag,
"%30d", &tag_from_sdp) != 1 || tag_from_sdp < 0 || tag_from_sdp > 999999999) {
877 for (tmp = srtp; tmp && tmp->
crypto && tmp->
crypto->
tag != tag_from_sdp;) {
903 if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_80")) {
906 key_len_expected = 30;
907 }
else if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_32")) {
910 key_len_expected = 30;
911#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
912 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_80")) {
916 key_len_expected = 38;
917 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_32")) {
921 key_len_expected = 38;
923 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_80")) {
928 key_len_expected = 38;
929 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_32")) {
934 key_len_expected = 38;
936#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
937 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_80")) {
941 key_len_expected = 46;
942 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_32")) {
946 key_len_expected = 46;
948 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_80")) {
953 key_len_expected = 46;
954 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_32")) {
959 key_len_expected = 46;
961#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
962 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM")) {
967 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM_8")) {
972#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
973 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM")) {
979 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM_8")) {
986 ast_debug(3,
"Unsupported crypto suite: %s\n", suite);
990 while ((key_param =
strsep(&key_params,
";"))) {
991 unsigned int n_lifetime;
999 if (strcmp(
method,
"inline")) {
1012 mki = strchr(lifetime,
':');
1020 if (mki && *mki !=
'1') {
1021 ast_log(
LOG_NOTICE,
"Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
1026 if (!strncmp(lifetime,
"2^", 2)) {
1027 char *lifetime_val = lifetime + 2;
1030 if (sscanf(lifetime_val,
"%30u", &n_lifetime) != 1) {
1031 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1035 if (n_lifetime > 48) {
1037 ast_log(
LOG_NOTICE,
"Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
1040 sdes_lifetime = pow(2, n_lifetime);
1043 if (sscanf(lifetime,
"%30u", &n_lifetime) != 1) {
1044 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1047 sdes_lifetime = n_lifetime;
1051 if (sdes_lifetime < 1048576) {
1052 ast_log(
LOG_NOTICE,
"Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
1057 ast_debug(2,
"Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
1058 attr, sdes_lifetime, mki ? mki :
"-");
1069 key_len_from_sdp =
ast_base64decode(remote_key, key_salt,
sizeof(remote_key));
1070 if (key_len_from_sdp != key_len_expected) {
1072 key_len_from_sdp, key_len_expected);
1084 ast_debug(1,
"SRTP remote key unchanged; maintaining current policy\n");
1090 "SRTP key buffer is %zu although it must be at least %d bytes\n",
1142 const int attr[][3] = {
1170#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
1173#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
1176#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
1179#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
1219 taglen = default_taglen_32 ? 32 : 80;
1250 srtp_install_event_handler(
NULL);
1251#ifdef HAVE_SRTP_SHUTDOWN
1282#ifdef HAVE_SRTP_GET_VERSION
1283 ast_verb(2,
"%s initialized\n", srtp_get_version_string());
1285 ast_verb(2,
"libsrtp initialized\n");
char * strsep(char **str, const char *delims)
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_t_ref(o, delta, tag)
#define ao2_iterator_next(iter)
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_t_find(container, arg, flags, tag)
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_t_link(container, obj, tag)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
#define ao2_t_unlink(container, obj, tag)
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Asterisk internal frame definitions.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_module_ref(mod)
Hold a reference to the module.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define SRTP_MASTER_KEY_LEN
static int policy_cmp_fn(void *obj, void *arg, int flags)
static struct ast_sdp_crypto * sdp_crypto_alloc(const int key_len)
static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy)
static int crypto_activate(struct ast_sdp_crypto *p, int suite_val, unsigned char *remote_key, int key_len, struct ast_rtp_instance *rtp)
static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
static const char * srtp_errstr(int err)
static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
static int ast_srtp_policy_set_master_key(struct ast_srtp_policy *policy, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len)
static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
static int set_crypto_policy(struct ast_srtp_policy *policy, int suite_val, const unsigned char *master_key, int key_len, unsigned long ssrc, int inbound)
static struct ast_sdp_crypto * res_sdp_crypto_alloc(void)
static int ast_srtp_change_source(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
static int res_srtp_init(void)
static struct ast_sdp_crypto * crypto_init_keys(struct ast_sdp_crypto *p, const int key_len)
static int res_sdp_crypto_parse_offer(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
static struct ast_srtp * res_srtp_new(void)
static int ast_srtp_replace(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
static struct ast_srtp_res srtp_res
static int ast_srtp_get_random(unsigned char *key, size_t len)
static void ast_srtp_destroy(struct ast_srtp *srtp)
static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
static struct ast_srtp_policy * ast_srtp_policy_alloc(void)
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
static int load_module(void)
static int unload_module(void)
static int policy_hash_fn(const void *obj, const int flags)
static struct ast_srtp_policy_res policy_res
static struct ast_srtp_policy * find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp)
static void res_srtp_shutdown(void)
static int res_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
static void srtp_event_cb(srtp_event_data_t *data)
static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp)
static const char * res_sdp_srtp_get_attr(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
static struct ast_sdp_crypto_api res_sdp_crypto_api
static void policy_destructor(void *obj)
static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data)
@ AST_AES_CM_128_HMAC_SHA1_80
@ AST_AES_CM_128_HMAC_SHA1_32
@ AST_AES_CM_256_HMAC_SHA1_32
@ AST_AES_CM_192_HMAC_SHA1_80
@ AST_AES_CM_256_HMAC_SHA1_80
@ AST_AES_CM_192_HMAC_SHA1_32
Pluggable RTP Architecture.
int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
void ast_rtp_engine_unregister_srtp(void)
@ AST_RTP_INSTANCE_STAT_LOCAL_SSRC
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
int ast_rtp_instance_add_srtp_policy(struct ast_rtp_instance *instance, struct ast_srtp_policy *remote_policy, struct ast_srtp_policy *local_policy, int rtcp)
Add or replace the SRTP policies for the given RTP instance.
SRTP and SDP Security descriptions.
int ast_sdp_crypto_register(struct ast_sdp_crypto_api *api)
Register SDP SRTP crypto processing routines.
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
#define AST_SRTP_CRYPTO_TAG_16
#define AST_SRTP_CRYPTO_TAG_80
#define AST_SRTP_CRYPTO_AES_256
#define AST_SRTP_CRYPTO_TAG_32
void ast_sdp_crypto_unregister(struct ast_sdp_crypto_api *api)
Unregister SDP SRTP crypto processing routines.
#define AST_SRTP_CRYPTO_TAG_8
#define AST_SRTP_CRYPTO_AES_192
#define AST_SRTP_CRYPTO_OLD_NAME
#define AST_SRTP_CRYPTO_OFFER_OK
#define err_status_cipher_fail
#define crypto_policy_set_aes_gcm_256_8_auth
#define crypto_policy_set_aes_cm_192_hmac_sha1_80
#define crypto_policy_set_aes_gcm_128_16_auth
#define crypto_policy_set_aes_cm_128_hmac_sha1_32
#define crypto_policy_set_aes_cm_128_hmac_sha1_80
#define err_status_init_fail
#define err_status_replay_old
#define err_status_algo_fail
#define crypto_policy_set_aes_gcm_256_16_auth
#define AES_128_GCM_KEYSIZE_WSALT
#define err_status_no_ctx
#define crypto_policy_set_aes_cm_192_hmac_sha1_32
#define err_status_dealloc_fail
#define crypto_policy_set_aes_cm_256_hmac_sha1_32
#define crypto_policy_set_aes_cm_256_hmac_sha1_80
#define err_status_alloc_fail
#define err_status_no_such_op
#define err_status_key_expired
#define AES_256_GCM_KEYSIZE_WSALT
#define crypto_policy_set_aes_gcm_128_8_auth
#define err_status_cant_check
#define err_status_bad_param
#define err_status_auth_fail
#define err_status_terminus
#define err_status_replay_fail
static force_inline int attribute_pure ast_strlen_zero(const char *s)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
sdp_crypto_destroy_cb dtor
unsigned char local_key[SRTP_MAX_KEY_LEN]
char local_key64[((SRTP_MAX_KEY_LEN) *8+5)/6+1]
unsigned char remote_key[SRTP_MAX_KEY_LEN]
structure for secure RTP audio
struct ast_sdp_srtp::@283 sdp_srtp_list
struct ast_sdp_crypto * crypto
int(* no_ctx)(struct ast_rtp_instance *rtp, unsigned long ssrc, void *data)
void(* destroy)(struct ast_srtp_policy *policy)
int(* set_master_key)(struct ast_srtp_policy *policy, const unsigned char *key, size_t key_len, const unsigned char *salt, size_t salt_len)
void(* set_ssrc)(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
int(* set_suite)(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
struct ast_srtp_policy *(* alloc)(void)
int(* get_random)(unsigned char *key, size_t len)
int(* create)(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
struct ao2_container * policies
const struct ast_srtp_cb * cb
struct ast_rtp_instance * rtp
unsigned char rtcpbuf[8192+AST_FRIENDLY_OFFSET]
#define ast_test_flag(p, flag)
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
#define ast_clear_flag(p, flag)
#define ast_set_flag(p, flag)