42 #include <srtp/srtp.h>
43 #include <srtp/crypto_kernel.h>
113 return "nothing to report";
114 case err_status_fail:
115 return "unspecified failure";
116 case err_status_bad_param:
117 return "unsupported parameter";
118 case err_status_alloc_fail:
119 return "couldn't allocate memory";
120 case err_status_dealloc_fail:
121 return "couldn't deallocate properly";
122 case err_status_init_fail:
123 return "couldn't initialize";
124 case err_status_terminus:
125 return "can't process as much data as requested";
126 case err_status_auth_fail:
127 return "authentication failure";
128 case err_status_cipher_fail:
129 return "cipher failure";
130 case err_status_replay_fail:
131 return "replay check failed (bad index)";
132 case err_status_replay_old:
133 return "replay check failed (index too old)";
134 case err_status_algo_fail:
135 return "algorithm failed test routine";
136 case err_status_no_such_op:
137 return "unsupported operation";
138 case err_status_no_ctx:
139 return "no appropriate context found";
140 case err_status_cant_check:
141 return "unable to perform desired validation";
142 case err_status_key_expired:
143 return "can't use key any more";
153 return policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type;
160 return one->
sp.ssrc.type == two->sp.ssrc.type && one->
sp.ssrc.value == two->sp.ssrc.value;
167 .ssrc.type = policy->ssrc.type,
168 .ssrc.value = policy->ssrc.value,
199 switch (data->event) {
200 case event_ssrc_collision:
203 case event_key_soft_limit:
206 case event_key_hard_limit:
209 case event_packet_index_limit:
210 ast_debug(1,
"event_packet_index_limit\n");
216 unsigned long ssrc,
int inbound)
219 policy->
sp.ssrc.type = ssrc_specific;
220 policy->
sp.ssrc.value = ssrc;
222 policy->
sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
230 if (policy->
sp.key) {
232 policy->
sp.key = NULL;
249 ao2_t_ref(policy, -1,
"Destroying policy");
256 p->cipher_type = AES_128_ICM;
257 p->cipher_key_len = 30;
258 p->auth_type = HMAC_SHA1;
259 p->auth_key_len = 20;
260 p->auth_tag_len = 10;
261 p->sec_serv = sec_serv_conf_and_auth;
265 p->cipher_type = AES_128_ICM;
266 p->cipher_key_len = 30;
267 p->auth_type = HMAC_SHA1;
268 p->auth_key_len = 20;
270 p->sec_serv = sec_serv_conf_and_auth;
286 size_t size = key_len + salt_len;
287 unsigned char *master_key;
289 if (policy->
sp.key) {
291 policy->
sp.key = NULL;
298 memcpy(master_key, key, key_len);
299 memcpy(master_key + key_len, salt, salt_len);
301 policy->
sp.key = master_key;
308 return crypto_get_random(key, len) != err_status_ok ? -1: 0;
331 for (i = 0; i < 2; i++) {
332 res = rtcp ? srtp_unprotect_rtcp(srtp->
session, buf, len) : srtp_unprotect(srtp->
session, buf, len);
333 if (res != err_status_no_ctx) {
349 if (retry == 0 && res == err_status_replay_old) {
358 ast_debug(5,
"SRTP destroy before re-create\n");
370 int res_srtp_create = srtp_create(&srtp->
session, &policy->
sp);
371 if (res_srtp_create == err_status_ok) {
372 ast_debug(5,
"SRTP re-created with first policy\n");
373 ao2_t_ref(policy, -1,
"Unreffing first policy for re-creating srtp session");
376 if (policies_count > 1) {
377 ast_debug(5,
"Add all the other %d policies\n",
380 srtp_add_stream(srtp->
session, &policy->
sp);
381 ao2_t_ref(policy, -1,
"Unreffing n-th policy for re-creating srtp session");
394 ao2_t_ref(policy, -1,
"Unreffing first policy after srtp_create failed");
405 if (res != err_status_ok && res != err_status_replay_fail ) {
406 if ((srtp->
warned >= 10) && !((srtp->
warned - 10) % 100)) {
422 unsigned char *localbuf;
424 if ((*len + SRTP_MAX_TRAILER_LEN) >
sizeof(srtp->
buf)) {
430 memcpy(localbuf, *buf, *len);
432 if ((res = rtcp ? srtp_protect_rtcp(srtp->
session, localbuf, len) : srtp_protect(srtp->
session, localbuf, len)) != err_status_ok && res != err_status_replay_fail) {
451 if (srtp_create(&temp->
session, &policy->
sp) != err_status_ok) {
461 ao2_t_link((*srtp)->policies, policy,
"Created initial policy");
468 if ((*srtp) != NULL) {
493 if (policy->
sp.ssrc.type != ssrc_specific) {
495 ao2_t_ref(match, -1,
"Unreffing already existing policy");
498 if (srtp_remove_stream(srtp->
session, match->
sp.ssrc.value) != err_status_ok) {
502 ao2_t_ref(match, -1,
"Unreffing already existing policy");
506 ast_debug(3,
"Adding new policy for %s %u\n",
507 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
508 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
509 if (srtp_add_stream(srtp->
session, &policy->
sp) != err_status_ok) {
511 policy->
sp.ssrc.type == ssrc_specific ?
"SSRC" :
"type",
512 policy->
sp.ssrc.type == ssrc_specific ? policy->
sp.ssrc.value : policy->
sp.ssrc.type);
524 struct srtp_policy_t sp = {
525 .ssrc.type = ssrc_specific,
526 .ssrc.value = from_ssrc,
534 match->
sp.ssrc.value = to_ssrc;
537 }
else if ((status = srtp_remove_stream(srtp->
session, from_ssrc))) {
538 ast_debug(3,
"Couldn't remove stream (%u)\n", status);
540 ao2_t_ref(match, -1,
"Unreffing found policy in change_source");
548 srtp_install_event_handler(NULL);
550 #ifdef HAVE_SRTP_SHUTDOWN
562 if (srtp_init() != err_status_ok) {
#define ao2_t_ref(o, delta, tag)
Reference/unreference an object and return the old refcount.
#define ao2_t_find(arg1, arg2, arg3, arg4)
static struct ast_srtp_policy * ast_srtp_policy_alloc(void)
Asterisk locking-related definitions:
static int unload_module(void)
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
void ast_module_unref(struct ast_module *)
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 ao2_t_alloc(data_size, destructor_fn, debug_msg)
Allocate and initialize an object.
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 ao2_iterator_next(arg1)
static void res_srtp_shutdown(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)
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)
int(* create)(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
struct ao2_container * policies
#define ao2_t_container_alloc(arg1, arg2, arg3, arg4)
Allocate and initialize a container with the desired number of buckets.
static struct ast_srtp_res srtp_res
static void ast_srtp_destroy(struct ast_srtp *srtp)
void ast_rtp_engine_unregister_srtp(void)
#define ao2_t_link(arg1, arg2, arg3)
Add an object to a container.
#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 AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
struct ast_srtp_policy *(* alloc)(void)
Scheduler Routines (derived from cheops)
static int load_module(void)
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 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 ao2_t_unlink(arg1, arg2, arg3)
Remove an object from a container.
static int ast_srtp_get_random(unsigned char *key, size_t len)
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.
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)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
int(* no_ctx)(struct ast_rtp_instance *rtp, unsigned long ssrc, void *data)
static void policy_destructor(void *obj)
static struct ast_srtp * res_srtp_new(void)
static const char * srtp_errstr(int err)
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp)
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound)
static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
static void srtp_event_cb(srtp_event_data_t *data)
Options provided by main asterisk program.
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
#define ASTERISK_GPL_KEY
The text the key() function should return.
Pluggable RTP Architecture.
Asterisk module definitions.
static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
struct ast_rtp_instance * rtp
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static int policy_cmp_fn(void *obj, void *arg, int flags)
struct ast_module * ast_module_ref(struct ast_module *)