44#if HAVE_SRTP_VERSION > 1
45# include <srtp2/srtp.h>
47# include <openssl/rand.h>
49# include <srtp/srtp.h>
51# include <openssl/rand.h>
53# include <srtp/crypto_kernel.h>
127 return "nothing to report";
129 return "unspecified failure";
131 return "unsupported parameter";
133 return "couldn't allocate memory";
135 return "couldn't deallocate properly";
137 return "couldn't initialize";
139 return "can't process as much data as requested";
141 return "authentication failure";
143 return "cipher failure";
145 return "replay check failed (bad index)";
147 return "replay check failed (index too old)";
149 return "algorithm failed test routine";
151 return "unsupported operation";
153 return "no appropriate context found";
155 return "unable to perform desired validation";
157 return "can't use key any more";
167 return policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type;
174 return one->
sp.ssrc.type == two->sp.ssrc.type && one->
sp.ssrc.value == two->sp.ssrc.value;
181 .ssrc.type = policy->ssrc.type,
182 .ssrc.value = policy->ssrc.value,
215 switch (
data->event) {
216 case event_ssrc_collision:
219 case event_key_soft_limit:
222 case event_key_hard_limit:
225 case event_packet_index_limit:
226 ast_debug(1,
"event_packet_index_limit\n");
232 unsigned long ssrc,
int inbound)
235 policy->
sp.ssrc.type = ssrc_specific;
236 policy->
sp.ssrc.value = ssrc;
238 policy->
sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
246 if (policy->
sp.key) {
265 ao2_t_ref(policy, -1,
"Destroying policy");
279#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
288#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
297#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
306#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
329 size_t size = key_len + salt_len;
330 unsigned char *master_key;
332 if (policy->
sp.key) {
341 memcpy(master_key, key, key_len);
342 memcpy(master_key + key_len, salt, salt_len);
344 policy->
sp.key = master_key;
352 return RAND_bytes(key,
len) > 0 ? 0: -1;
373 int rtcp = (flags & 0x01) >> 0;
374 int retry = (flags & 0x02) >> 1;
380 ast_log(
LOG_ERROR,
"SRTP unprotect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
385 for (i = 0; i < 2; i++) {
412 ast_debug(5,
"SRTP destroy before re-create\n");
424 int res_srtp_create = srtp_create(&srtp->
session, &policy->
sp);
426 ast_debug(5,
"SRTP re-created with first policy\n");
427 ao2_t_ref(policy, -1,
"Unreffing first policy for re-creating srtp session");
430 if (policies_count > 1) {
431 ast_debug(5,
"Add all the other %d policies\n",
434 srtp_add_stream(srtp->
session, &policy->
sp);
435 ao2_t_ref(policy, -1,
"Unreffing n-th policy for re-creating srtp session");
448 ao2_t_ref(policy, -1,
"Unreffing first policy after srtp_create failed");
470 ast_verb(2,
"SRTCP unprotect failed on SSRC %u because of %s\n",
473 if ((srtp->
warned >= 10) && !((srtp->
warned - 10) % 150)) {
474 ast_verb(2,
"SRTP unprotect failed on SSRC %u because of %s %d\n",
491 unsigned char *localbuf;
494 ast_log(
LOG_ERROR,
"SRTP protect %s - missing session\n", rtcp ?
"rtcp" :
"rtp");
499 if ((*
len + SRTP_MAX_TRAILER_LEN) >
sizeof(srtp->
buf)) {
505 memcpy(localbuf, *
buf, *
len);
532 ast_log(
LOG_ERROR,
"Failed to create srtp session on rtp instance (%p) - %s\n",
540 ao2_t_link((*srtp)->policies, policy,
"Created initial policy");
556 "- keeping old\n", *srtp,
rtp);
581 if (policy->
sp.ssrc.type != ssrc_specific) {
594 ast_debug(3,
"Adding new policy for %s %u\n",
595 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
596 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
599 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
600 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
612 struct srtp_policy_t sp = {
613 .ssrc.type = ssrc_specific,
614 .ssrc.value = from_ssrc,
622 match->sp.ssrc.value = to_ssrc;
625 }
else if ((
status = srtp_remove_stream(srtp->
session, from_ssrc))) {
713 if ((taglen & 0x007f) == 8) {
715 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
716 }
else if ((taglen & 0x007f) == 16) {
719 }
else if ((taglen & 0x0300) && !(taglen & 0x0080)) {
721 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
724 p->
tag, 128 + ((taglen & 0x0300) >> 2), taglen & 0x007f, p->
local_key64);
779 if (
set_crypto_policy(remote_policy, suite_val, remote_key, key_len, 0, 1) < 0) {
789 ast_debug(1 ,
"SRTP policy activated\n");
809 char *key_params =
NULL;
810 char *key_param =
NULL;
811 char *session_params =
NULL;
812 char *key_salt =
NULL;
813 char *lifetime =
NULL;
816 int key_len_from_sdp;
817 int key_len_expected;
820 unsigned char remote_key[SRTP_MAX_KEY_LEN];
822 double sdes_lifetime;
833 if (!tag || !suite) {
839 if (sscanf(tag,
"%30d", &tag_from_sdp) != 1 || tag_from_sdp < 0 || tag_from_sdp > 999999999) {
851 for (
tmp = srtp;
tmp &&
tmp->crypto &&
tmp->crypto->tag != tag_from_sdp;) {
877 if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_80")) {
880 key_len_expected = 30;
881 }
else if (!strcmp(suite,
"AES_CM_128_HMAC_SHA1_32")) {
884 key_len_expected = 30;
885#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
886 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_80")) {
890 key_len_expected = 38;
891 }
else if (!strcmp(suite,
"AES_192_CM_HMAC_SHA1_32")) {
895 key_len_expected = 38;
897 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_80")) {
902 key_len_expected = 38;
903 }
else if (!strcmp(suite,
"AES_CM_192_HMAC_SHA1_32")) {
908 key_len_expected = 38;
910#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
911 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_80")) {
915 key_len_expected = 46;
916 }
else if (!strcmp(suite,
"AES_256_CM_HMAC_SHA1_32")) {
920 key_len_expected = 46;
922 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_80")) {
927 key_len_expected = 46;
928 }
else if (!strcmp(suite,
"AES_CM_256_HMAC_SHA1_32")) {
933 key_len_expected = 46;
935#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
936 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM")) {
941 }
else if (!strcmp(suite,
"AEAD_AES_128_GCM_8")) {
946#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
947 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM")) {
953 }
else if (!strcmp(suite,
"AEAD_AES_256_GCM_8")) {
960 ast_verb(1,
"Unsupported crypto suite: %s\n", suite);
964 while ((key_param =
strsep(&key_params,
";"))) {
965 unsigned int n_lifetime;
973 if (strcmp(
method,
"inline")) {
986 mki = strchr(lifetime,
':');
994 if (mki && *mki !=
'1') {
995 ast_log(
LOG_NOTICE,
"Crypto MKI handling is not supported: ignoring attribute %s\n", attr);
1000 if (!strncmp(lifetime,
"2^", 2)) {
1001 char *lifetime_val = lifetime + 2;
1004 if (sscanf(lifetime_val,
"%30u", &n_lifetime) != 1) {
1005 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1009 if (n_lifetime > 48) {
1011 ast_log(
LOG_NOTICE,
"Crypto lifetime exponent of '%u' is a bit large; using 48\n", n_lifetime);
1014 sdes_lifetime = pow(2, n_lifetime);
1017 if (sscanf(lifetime,
"%30u", &n_lifetime) != 1) {
1018 ast_log(
LOG_NOTICE,
"Failed to parse lifetime value in crypto attribute: %s\n", attr);
1021 sdes_lifetime = n_lifetime;
1025 if (sdes_lifetime < 1048576) {
1026 ast_log(
LOG_NOTICE,
"Rejecting crypto attribute '%s': lifetime '%f' too short\n", attr, sdes_lifetime);
1031 ast_debug(2,
"Crypto attribute '%s' accepted with lifetime '%f', MKI '%s'\n",
1032 attr, sdes_lifetime, mki ? mki :
"-");
1043 key_len_from_sdp =
ast_base64decode(remote_key, key_salt,
sizeof(remote_key));
1044 if (key_len_from_sdp != key_len_expected) {
1046 key_len_from_sdp, key_len_expected);
1058 ast_debug(1,
"SRTP remote key unchanged; maintaining current policy\n");
1064 "SRTP key buffer is %zu although it must be at least %d bytes\n",
1116 const int attr[][3] = {
1144#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM)
1147#if defined(HAVE_SRTP_256) && defined(ENABLE_SRTP_AES_256)
1150#if defined(HAVE_SRTP_GCM) && defined(ENABLE_SRTP_AES_GCM) && defined(ENABLE_SRTP_AES_256)
1153#if defined(HAVE_SRTP_192) && defined(ENABLE_SRTP_AES_192)
1168 tmp->crypto->tag = (i + 1);
1193 taglen = default_taglen_32 ? 32 : 80;
1224 srtp_install_event_handler(
NULL);
1225#ifdef HAVE_SRTP_SHUTDOWN
1256#ifdef HAVE_SRTP_GET_VERSION
1257 ast_verb(2,
"%s initialized\n", srtp_get_version_string());
1259 ast_verb(2,
"libsrtp initialized\n");
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)
char * strsep(char **str, const char *delims)
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::@278 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)