2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2005, Mikael Magnusson
6 * Mikael Magnusson <mikma@users.sourceforge.net>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
18 * Builds on libSRTP http://srtp.sourceforge.net
23 * \brief Secure RTP (SRTP)
26 * Specified in RFC 3711.
28 * \author Mikael Magnusson <mikma@users.sourceforge.net>
35 /* The SIP channel will automatically use sdescriptions if received in a SDP offer,
36 and res_srtp is loaded. SRTP with sdescriptions key exchange can be activated
37 in outgoing offers by setting _SIPSRTP_CRYPTO=enable in extension.conf before executing Dial
39 The dial fails if the callee doesn't support SRTP and sdescriptions.
41 exten => 2345,1,Set(_SIPSRTP_CRYPTO=enable)
42 exten => 2345,2,Dial(SIP/1001)
47 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
49 #include <srtp/srtp.h>
51 #include "asterisk/lock.h"
52 #include "asterisk/sched.h"
53 #include "asterisk/module.h"
54 #include "asterisk/options.h"
55 #include "asterisk/rtp_engine.h"
58 struct ast_rtp_instance *rtp;
60 const struct ast_srtp_cb *cb;
62 unsigned char buf[8192 + AST_FRIENDLY_OFFSET];
63 unsigned int has_stream:1;
66 struct ast_srtp_policy {
70 static int g_initialized = 0;
73 static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy);
74 static void ast_srtp_destroy(struct ast_srtp *srtp);
75 static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy);
77 static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp);
78 static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp);
79 static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data);
80 static int ast_srtp_get_random(unsigned char *key, size_t len);
82 /* Policy functions */
83 static struct ast_srtp_policy *ast_srtp_policy_alloc(void);
84 static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy);
85 static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite);
86 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);
87 static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy, unsigned long ssrc, int inbound);
89 static struct ast_srtp_res srtp_res = {
90 .create = ast_srtp_create,
91 .destroy = ast_srtp_destroy,
92 .add_stream = ast_srtp_add_stream,
93 .set_cb = ast_srtp_set_cb,
94 .unprotect = ast_srtp_unprotect,
95 .protect = ast_srtp_protect,
96 .get_random = ast_srtp_get_random
99 static struct ast_srtp_policy_res policy_res = {
100 .alloc = ast_srtp_policy_alloc,
101 .destroy = ast_srtp_policy_destroy,
102 .set_suite = ast_srtp_policy_set_suite,
103 .set_master_key = ast_srtp_policy_set_master_key,
104 .set_ssrc = ast_srtp_policy_set_ssrc
107 static const char *srtp_errstr(int err)
111 return "nothing to report";
112 case err_status_fail:
113 return "unspecified failure";
114 case err_status_bad_param:
115 return "unsupported parameter";
116 case err_status_alloc_fail:
117 return "couldn't allocate memory";
118 case err_status_dealloc_fail:
119 return "couldn't deallocate properly";
120 case err_status_init_fail:
121 return "couldn't initialize";
122 case err_status_terminus:
123 return "can't process as much data as requested";
124 case err_status_auth_fail:
125 return "authentication failure";
126 case err_status_cipher_fail:
127 return "cipher failure";
128 case err_status_replay_fail:
129 return "replay check failed (bad index)";
130 case err_status_replay_old:
131 return "replay check failed (index too old)";
132 case err_status_algo_fail:
133 return "algorithm failed test routine";
134 case err_status_no_such_op:
135 return "unsupported operation";
136 case err_status_no_ctx:
137 return "no appropriate context found";
138 case err_status_cant_check:
139 return "unable to perform desired validation";
140 case err_status_key_expired:
141 return "can't use key any more";
147 static struct ast_srtp *res_srtp_new(void)
149 struct ast_srtp *srtp;
151 if (!(srtp = ast_calloc(1, sizeof(*srtp)))) {
152 ast_log(LOG_ERROR, "Unable to allocate memory for srtp\n");
160 struct ast_srtp_policy
162 static void srtp_event_cb(srtp_event_data_t *data)
164 switch (data->event) {
165 case event_ssrc_collision:
166 ast_debug(1, "SSRC collision\n");
168 case event_key_soft_limit:
169 ast_debug(1, "event_key_soft_limit\n");
171 case event_key_hard_limit:
172 ast_debug(1, "event_key_hard_limit\n");
174 case event_packet_index_limit:
175 ast_debug(1, "event_packet_index_limit\n");
180 static void ast_srtp_policy_set_ssrc(struct ast_srtp_policy *policy,
181 unsigned long ssrc, int inbound)
184 policy->sp.ssrc.type = ssrc_specific;
185 policy->sp.ssrc.value = ssrc;
187 policy->sp.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
191 static struct ast_srtp_policy *ast_srtp_policy_alloc()
193 struct ast_srtp_policy *tmp;
195 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
196 ast_log(LOG_ERROR, "Unable to allocate memory for srtp_policy\n");
202 static void ast_srtp_policy_destroy(struct ast_srtp_policy *policy)
204 if (policy->sp.key) {
205 ast_free(policy->sp.key);
206 policy->sp.key = NULL;
211 static int policy_set_suite(crypto_policy_t *p, enum ast_srtp_suite suite)
214 case AST_AES_CM_128_HMAC_SHA1_80:
215 p->cipher_type = AES_128_ICM;
216 p->cipher_key_len = 30;
217 p->auth_type = HMAC_SHA1;
218 p->auth_key_len = 20;
219 p->auth_tag_len = 10;
220 p->sec_serv = sec_serv_conf_and_auth;
223 case AST_AES_CM_128_HMAC_SHA1_32:
224 p->cipher_type = AES_128_ICM;
225 p->cipher_key_len = 30;
226 p->auth_type = HMAC_SHA1;
227 p->auth_key_len = 20;
229 p->sec_serv = sec_serv_conf_and_auth;
233 ast_log(LOG_ERROR, "Invalid crypto suite: %d\n", suite);
238 static int ast_srtp_policy_set_suite(struct ast_srtp_policy *policy, enum ast_srtp_suite suite)
240 return policy_set_suite(&policy->sp.rtp, suite) | policy_set_suite(&policy->sp.rtcp, suite);
243 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)
245 size_t size = key_len + salt_len;
246 unsigned char *master_key;
248 if (policy->sp.key) {
249 ast_free(policy->sp.key);
250 policy->sp.key = NULL;
253 if (!(master_key = ast_calloc(1, size))) {
257 memcpy(master_key, key, key_len);
258 memcpy(master_key + key_len, salt, salt_len);
260 policy->sp.key = master_key;
265 static int ast_srtp_get_random(unsigned char *key, size_t len)
267 return crypto_get_random(key, len) != err_status_ok ? -1: 0;
270 static void ast_srtp_set_cb(struct ast_srtp *srtp, const struct ast_srtp_cb *cb, void *data)
280 /* Vtable functions */
281 static int ast_srtp_unprotect(struct ast_srtp *srtp, void *buf, int *len, int rtcp)
285 struct ast_rtp_instance_stats stats = {0,};
287 for (i = 0; i < 2; i++) {
288 res = rtcp ? srtp_unprotect_rtcp(srtp->session, buf, len) : srtp_unprotect(srtp->session, buf, len);
289 if (res != err_status_no_ctx) {
293 if (srtp->cb && srtp->cb->no_ctx) {
294 if (ast_rtp_instance_get_stats(srtp->rtp, &stats, AST_RTP_INSTANCE_STAT_REMOTE_SSRC)) {
297 if (srtp->cb->no_ctx(srtp->rtp, stats.remote_ssrc, srtp->data) < 0) {
305 if (res != err_status_ok && res != err_status_replay_fail ) {
306 ast_debug(1, "SRTP unprotect: %s\n", srtp_errstr(res));
313 static int ast_srtp_protect(struct ast_srtp *srtp, void **buf, int *len, int rtcp)
317 if ((*len + SRTP_MAX_TRAILER_LEN) > sizeof(srtp->buf)) {
321 memcpy(srtp->buf, *buf, *len);
323 if ((res = rtcp ? srtp_protect_rtcp(srtp->session, srtp->buf, len) : srtp_protect(srtp->session, srtp->buf, len)) != err_status_ok && res != err_status_replay_fail) {
324 ast_debug(1, "SRTP protect: %s\n", srtp_errstr(res));
332 static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp, struct ast_srtp_policy *policy)
334 struct ast_srtp *temp;
336 if (!(temp = res_srtp_new())) {
340 if (srtp_create(&temp->session, &policy->sp) != err_status_ok) {
350 static void ast_srtp_destroy(struct ast_srtp *srtp)
353 srtp_dealloc(srtp->session);
359 static int ast_srtp_add_stream(struct ast_srtp *srtp, struct ast_srtp_policy *policy)
361 if (!srtp->has_stream && srtp_add_stream(srtp->session, &policy->sp) != err_status_ok) {
365 srtp->has_stream = 1;
370 static int res_srtp_init(void)
376 if (srtp_init() != err_status_ok) {
380 srtp_install_event_handler(srtp_event_cb);
382 return ast_rtp_engine_register_srtp(&srtp_res, &policy_res);
389 static int load_module(void)
391 return res_srtp_init();
394 static int unload_module(void)
396 ast_rtp_engine_unregister_srtp();
400 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Secure RTP (SRTP)",
402 .unload = unload_module,