43 #if HAVE_SRTP_VERSION > 1 44 # include <srtp2/srtp.h> 46 # include <openssl/rand.h> 48 # include <srtp/srtp.h> 50 # include <openssl/rand.h> 52 # include <srtp/crypto_kernel.h> 126 return "nothing to report";
128 return "unspecified failure";
130 return "unsupported parameter";
132 return "couldn't allocate memory";
134 return "couldn't deallocate properly";
136 return "couldn't initialize";
138 return "can't process as much data as requested";
140 return "authentication failure";
142 return "cipher failure";
144 return "replay check failed (bad index)";
146 return "replay check failed (index too old)";
148 return "algorithm failed test routine";
150 return "unsupported operation";
152 return "no appropriate context found";
154 return "unable to perform desired validation";
156 return "can't use key any more";
166 return policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type;
173 return one->
sp.ssrc.type == two->sp.ssrc.type && one->
sp.ssrc.value == two->sp.ssrc.value;
180 .ssrc.type = policy->ssrc.type,
181 .ssrc.value = policy->ssrc.value,
214 switch (data->event) {
215 case event_ssrc_collision:
218 case event_key_soft_limit:
221 case event_key_hard_limit:
224 case event_packet_index_limit:
225 ast_debug(1,
"event_packet_index_limit\n");
231 unsigned long ssrc,
int inbound)
234 policy->
sp.ssrc.type = ssrc_specific;
235 policy->
sp.ssrc.value = ssrc;
237 policy->
sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
245 if (policy->
sp.key) {
264 ao2_t_ref(policy, -1,
"Destroying policy");
327 size_t size = key_len + salt_len;
328 unsigned char *master_key;
330 if (policy->
sp.key) {
339 memcpy(master_key, key, key_len);
340 memcpy(master_key + key_len, salt, salt_len);
342 policy->
sp.key = master_key;
350 return RAND_bytes(key, len) > 0 ? 0: -1;
371 int rtcp = (flags & 0x01) >> 0;
372 int retry = (flags & 0x02) >> 1;
378 ast_log(
LOG_ERROR,
"SRTP unprotect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
383 for (i = 0; i < 2; i++) {
384 res = rtcp ? srtp_unprotect_rtcp(srtp->
session, buf, len) : srtp_unprotect(srtp->
session, buf, len);
410 ast_debug(5,
"SRTP destroy before re-create\n");
422 int res_srtp_create = srtp_create(&srtp->
session, &policy->
sp);
424 ast_debug(5,
"SRTP re-created with first policy\n");
425 ao2_t_ref(policy, -1,
"Unreffing first policy for re-creating srtp session");
428 if (policies_count > 1) {
429 ast_debug(5,
"Add all the other %d policies\n",
432 srtp_add_stream(srtp->
session, &policy->
sp);
433 ao2_t_ref(policy, -1,
"Unreffing n-th policy for re-creating srtp session");
446 ao2_t_ref(policy, -1,
"Unreffing first policy after srtp_create failed");
468 ast_verb(2,
"SRTCP unprotect failed on SSRC %u because of %s\n",
471 if ((srtp->
warned >= 10) && !((srtp->
warned - 10) % 150)) {
472 ast_verb(2,
"SRTP unprotect failed on SSRC %u because of %s %d\n",
489 unsigned char *localbuf;
492 ast_log(
LOG_ERROR,
"SRTP protect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
497 if ((*len + SRTP_MAX_TRAILER_LEN) >
sizeof(srtp->
buf)) {
503 memcpy(localbuf, *buf, *len);
525 status = srtp_create(&temp->
session, &policy->
sp);
530 ast_log(
LOG_ERROR,
"Failed to create srtp session on rtp instance (%p) - %s\n",
538 ao2_t_link((*srtp)->policies, policy,
"Created initial policy");
554 "- keeping old\n", *srtp, rtp);
579 if (policy->
sp.ssrc.type != ssrc_specific) {
581 ao2_t_ref(match, -1,
"Unreffing already existing policy");
588 ao2_t_ref(match, -1,
"Unreffing already existing policy");
592 ast_debug(3,
"Adding new policy for %s %u\n",
593 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
594 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
597 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
598 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
610 struct srtp_policy_t sp = {
611 .ssrc.type = ssrc_specific,
612 .ssrc.value = from_ssrc,
620 match->
sp.ssrc.value = to_ssrc;
623 }
else if ((status = srtp_remove_stream(srtp->
session, from_ssrc))) {
624 ast_debug(3,
"Couldn't remove stream (%u)\n", status);
626 ao2_t_ref(match, -1,
"Unreffing found policy in change_source");
634 unsigned char local_key[SRTP_MAX_KEY_LEN];
636 char local_key64[((SRTP_MAX_KEY_LEN) * 8 + 5) / 6 + 1];
637 unsigned char remote_key[SRTP_MAX_KEY_LEN];
711 if ((taglen & 0x007f) == 8) {
713 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
714 }
else if ((taglen & 0x007f) == 16) {
717 }
else if ((taglen & 0x0300) && !(taglen & 0x0080)) {
719 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
722 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
740 if (policy_res.
set_suite(policy, suite_val)) {
745 policy_res.
set_ssrc(policy, ssrc, inbound);
761 if (!(local_policy = policy_res.
alloc())) {
765 if (!(remote_policy = policy_res.
alloc())) {
777 if (
set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
787 ast_debug(1 ,
"SRTP policy activated\n");
792 policy_res.
destroy(local_policy);
796 policy_res.
destroy(remote_policy);
807 char *key_params =
NULL;
808 char *key_param =
NULL;
809 char *session_params =
NULL;
810 char *key_salt =
NULL;
811 char *lifetime =
NULL;
814 int key_len_from_sdp;
815 int key_len_expected;
818 unsigned char remote_key[SRTP_MAX_KEY_LEN];
820 double sdes_lifetime;
827 suite =
strsep(&str,
" ");
828 key_params =
strsep(&str,
" ");
829 session_params =
strsep(&str,
" ");
831 if (!tag || !suite) {
837 if (sscanf(tag,
"%30d", &tag_from_sdp) != 1 || tag_from_sdp < 0 || tag_from_sdp > 999999999) {
849 for (tmp = srtp; tmp && tmp->
crypto && tmp->
crypto->
tag != tag_from_sdp;) {
864 crypto->
tag = tag_from_sdp;
875 if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_80")) {
878 key_len_expected = 30;
879 }
else if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_32")) {
882 key_len_expected = 30;
884 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_80")) {
888 key_len_expected = 38;
889 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_32")) {
893 key_len_expected = 38;
895 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_80")) {
900 key_len_expected = 38;
901 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_32")) {
906 key_len_expected = 38;
909 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_80")) {
913 key_len_expected = 46;
914 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_32")) {
918 key_len_expected = 46;
920 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_80")) {
925 key_len_expected = 46;
926 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_32")) {
931 key_len_expected = 46;
934 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM")) {
938 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM")) {
944 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM_8")) {
948 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM_8")) {
955 ast_verb(1,
"Unsupported crypto suite: %s\n", suite);
959 while ((key_param =
strsep(&key_params,
";"))) {
960 unsigned int n_lifetime;
964 method =
strsep(&key_param,
":");
965 info =
strsep(&key_param,
";");
968 if (strcmp(method,
"inline")) {
972 key_salt =
strsep(&info,
"|");
975 lifetime =
strsep(&info,
"|");
981 mki = strchr(lifetime,
':');
989 if (mki && *mki !=
'1') {
990 ast_log(
LOG_NOTICE,
"Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
995 if (!strncmp(lifetime,
"2^", 2)) {
996 char *lifetime_val = lifetime + 2;
999 if (sscanf(lifetime_val,
"%30u", &n_lifetime) != 1) {
1000 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1004 if (n_lifetime > 48) {
1006 ast_log(
LOG_NOTICE,
"Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
1009 sdes_lifetime = pow(2, n_lifetime);
1012 if (sscanf(lifetime,
"%30u", &n_lifetime) != 1) {
1013 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1016 sdes_lifetime = n_lifetime;
1020 if (sdes_lifetime < 1048576) {
1021 ast_log(
LOG_NOTICE,
"Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
1026 ast_debug(2,
"Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
1027 attr, sdes_lifetime, mki ? mki :
"-");
1038 key_len_from_sdp =
ast_base64decode(remote_key, key_salt,
sizeof(remote_key));
1039 if (key_len_from_sdp != key_len_expected) {
1041 key_len_from_sdp, key_len_expected);
1048 if (crypto->
key_len != key_len_from_sdp) {
1052 }
else if (!memcmp(crypto->
remote_key, remote_key, key_len_from_sdp)) {
1053 ast_debug(1,
"SRTP remote key unchanged; maintaining current policy\n");
1057 if (key_len_from_sdp >
sizeof(crypto->
remote_key)) {
1059 "SRTP key buffer is %zu although it must be at least %d bytes\n",
1060 sizeof(crypto->
remote_key), key_len_from_sdp);
1063 memcpy(crypto->
remote_key, remote_key, key_len_from_sdp);
1065 if (
crypto_activate(crypto, suite_val, remote_key, key_len_from_sdp, rtp) < 0) {
1111 const int attr[][3] = {
1139 #if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) 1142 #if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256) 1145 #if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256) 1148 #if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192) 1188 taglen = default_taglen_32 ? 32 : 80;
1219 srtp_install_event_handler(
NULL);
1220 #ifdef HAVE_SRTP_SHUTDOWN 1251 #ifdef HAVE_SRTP_GET_VERSION 1252 ast_verb(2,
"%s initialized\n", srtp_get_version_string());
1254 ast_verb(2,
"libsrtp initialized\n");
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
structure for secure RTP audio
static struct ast_sdp_crypto * sdp_crypto_alloc(const int key_len)
static struct ast_srtp_policy * ast_srtp_policy_alloc(void)
#define crypto_policy_set_aes_cm_192_hmac_sha1_32
static int unload_module(void)
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_sdp_crypto * res_sdp_crypto_alloc(void)
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static int policy_hash_fn(const void *obj, const int flags)
static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data)
#define crypto_policy_set_aes_cm_192_hmac_sha1_80
#define AST_SRTP_CRYPTO_OLD_NAME
#define ao2_t_alloc(data_size, destructor_fn, debug_msg)
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.
#define AES_128_GCM_KEYSIZE_WSALT
#define ast_test_flag(p, flag)
static int res_sdp_crypto_build_offer(struct ast_sdp_crypto *p, int taglen)
#define err_status_algo_fail
#define ast_set_flag(p, flag)
#define err_status_cant_check
static void res_srtp_shutdown(void)
struct ast_srtp_policy *(* alloc)(void)
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)
#define err_status_bad_param
unsigned char rtcpbuf[8192+AST_FRIENDLY_OFFSET]
static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
static void res_sdp_crypto_dtor(struct ast_sdp_crypto *crypto)
#define ao2_t_link(container, obj, tag)
Add an object to a container.
#define ao2_t_unlink(container, obj, tag)
Remove an object from a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
#define AST_SRTP_CRYPTO_TAG_16
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)
struct ao2_container * policies
#define crypto_policy_set_aes_cm_256_hmac_sha1_80
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.
static struct ast_srtp_res srtp_res
int(* set_suite)(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
static void ast_srtp_destroy(struct ast_srtp *srtp)
#define ast_verb(level,...)
void ast_rtp_engine_unregister_srtp(void)
#define err_status_dealloc_fail
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_module_unref(mod)
Release a reference to the module.
#define ast_strlen_zero(foo)
const struct ast_srtp_cb * cb
static struct ast_sdp_crypto_api res_sdp_crypto_api
#define crypto_policy_set_aes_cm_128_hmac_sha1_80
#define err_status_alloc_fail
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
sdp_crypto_destroy_cb dtor
#define ast_debug(level,...)
Log a DEBUG message.
static int ast_srtp_change_source(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
#define err_status_cipher_fail
#define AST_SRTP_CRYPTO_AES_192
#define err_status_replay_old
static struct ast_sdp_crypto * crypto_init_keys(struct ast_sdp_crypto *p, const int key_len)
#define err_status_no_such_op
void(* set_ssrc)(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
SRTP and SDP Security descriptions.
#define err_status_init_fail
Asterisk internal frame definitions.
#define AST_SRTP_CRYPTO_OFFER_OK
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int load_module(void)
struct ast_sdp_crypto * crypto
#define AST_SRTP_CRYPTO_TAG_80
#define err_status_auth_fail
static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy)
static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp)
static struct ast_srtp_policy_res policy_res
static const char * res_sdp_srtp_get_attr(struct ast_sdp_srtp *srtp, int dtls_enabled, int default_taglen_32)
unsigned char remote_key[SRTP_MAX_KEY_LEN]
#define crypto_policy_set_aes_gcm_128_16_auth
static struct ast_srtp_policy * find_policy(struct ast_srtp *srtp, const srtp_policy_t *policy, int flags)
int ast_rtp_engine_register_srtp(struct ast_srtp_res *srtp_res, struct ast_srtp_policy_res *policy_res)
#define crypto_policy_set_aes_gcm_256_8_auth
static int ast_srtp_get_random(unsigned char *key, size_t len)
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
#define crypto_policy_set_aes_gcm_128_8_auth
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)
#define err_status_no_ctx
static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define ao2_t_callback(c, flags, cb_fn, arg, tag)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
unsigned int ast_rtp_instance_get_ssrc(struct ast_rtp_instance *rtp)
Retrieve the local SSRC value that we will be using.
int(* no_ctx)(struct ast_rtp_instance *rtp, unsigned long ssrc, void *data)
static int res_srtp_init(void)
static int ast_srtp_replace(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
#define SRTP_MASTER_KEY_LEN
#define ao2_iterator_next(iter)
static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
static int crypto_activate(struct ast_sdp_crypto *p, int suite_val, unsigned char *remote_key, int key_len, struct ast_rtp_instance *rtp)
#define ast_calloc(num, len)
A wrapper for calloc()
struct ast_sdp_srtp * ast_sdp_srtp_alloc(void)
allocate a ast_sdp_srtp structure
#define ao2_t_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn, tag)
Allocate and initialize a hash container with the desired number of buckets.
static void policy_destructor(void *obj)
static struct ast_srtp * res_srtp_new(void)
#define crypto_policy_set_aes_gcm_256_16_auth
#define AST_SRTP_CRYPTO_TAG_8
static const char * srtp_errstr(int err)
struct ast_sdp_srtp::@318 sdp_srtp_list
#define ast_clear_flag(p, flag)
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp)
char * strsep(char **str, const char *delims)
#define AST_SRTP_CRYPTO_TAG_32
unsigned char local_key[SRTP_MAX_KEY_LEN]
#define err_status_replay_fail
#define AST_SRTP_CRYPTO_AES_256
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
#define err_status_key_expired
#define crypto_policy_set_aes_cm_128_hmac_sha1_32
#define AES_256_GCM_KEYSIZE_WSALT
static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
void ast_sdp_crypto_unregister(struct ast_sdp_crypto_api *api)
Unregister SDP SRTP crypto processing routines.
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
static void srtp_event_cb(srtp_event_data_t *data)
#define ao2_t_find(container, arg, flags, tag)
static int res_sdp_crypto_parse_offer(struct ast_rtp_instance *rtp, struct ast_sdp_srtp *srtp, const char *attr)
int ast_sdp_crypto_register(struct ast_sdp_crypto_api *api)
Register SDP SRTP crypto processing routines.
void(* destroy)(struct ast_srtp_policy *policy)
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
#define ASTERISK_GPL_KEY
The text the key() function should return.
Pluggable RTP Architecture.
#define err_status_terminus
Asterisk module definitions.
#define crypto_policy_set_aes_cm_256_hmac_sha1_32
struct ast_rtp_instance * rtp
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
int(* get_random)(unsigned char *key, size_t len)
char local_key64[((SRTP_MAX_KEY_LEN) *8+5)/6+1]
static int policy_cmp_fn(void *obj, void *arg, int flags)
int(* create)(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
#define ast_module_ref(mod)
Hold a reference to the module.