summaryrefslogtreecommitdiff
path: root/modules/srtp/srtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/srtp/srtp.c')
-rw-r--r--modules/srtp/srtp.c191
1 files changed, 59 insertions, 132 deletions
diff --git a/modules/srtp/srtp.c b/modules/srtp/srtp.c
index 8bda31a..cd8fbf6 100644
--- a/modules/srtp/srtp.c
+++ b/modules/srtp/srtp.c
@@ -3,21 +3,19 @@
*
* Copyright (C) 2010 Creytiv.com
*/
-#if defined (__GNUC__) && !defined (asm)
-#define asm __asm__ /* workaround */
-#endif
-#include <srtp/srtp.h>
#include <re.h>
#include <baresip.h>
#include "sdes.h"
+#define SRTP_MASTER_KEY_LEN 30
+
+
struct menc_st {
/* one SRTP session per media line */
- uint8_t key_tx[32]; /* 32 for alignment, only 30 used */
+ uint8_t key_tx[32];
uint8_t key_rx[32];
- srtp_t srtp_tx, srtp_rx;
- srtp_policy_t policy_tx, policy_rx;
+ struct srtp *srtp_tx, *srtp_rx;
bool use_srtp;
char *crypto_suite;
@@ -32,6 +30,8 @@ struct menc_st {
static const char aes_cm_128_hmac_sha1_32[] = "AES_CM_128_HMAC_SHA1_32";
static const char aes_cm_128_hmac_sha1_80[] = "AES_CM_128_HMAC_SHA1_80";
+static const char *preferred_suite = aes_cm_128_hmac_sha1_80;
+
static void destructor(void *arg)
{
@@ -46,10 +46,8 @@ static void destructor(void *arg)
mem_deref(st->rtpsock);
mem_deref(st->rtcpsock);
- if (st->srtp_tx)
- srtp_dealloc(st->srtp_tx);
- if (st->srtp_rx)
- srtp_dealloc(st->srtp_rx);
+ mem_deref(st->srtp_tx);
+ mem_deref(st->srtp_rx);
}
@@ -62,26 +60,6 @@ static bool cryptosuite_issupported(const struct pl *suite)
}
-static int errstatus_print(struct re_printf *pf, err_status_t e)
-{
- const char *s;
-
- switch (e) {
-
- case err_status_ok: s = "ok"; break;
- case err_status_fail: s = "fail"; break;
- case err_status_auth_fail: s = "auth_fail"; break;
- case err_status_cipher_fail: s = "cipher_fail"; break;
- case err_status_replay_fail: s = "replay_fail"; break;
-
- default:
- return re_hprintf(pf, "err=%d", e);
- }
-
- return re_hprintf(pf, "%s", s);
-}
-
-
/*
* See RFC 5764 figure 3:
*
@@ -120,49 +98,39 @@ static bool is_rtcp_packet(const struct mbuf *mb)
}
-static int start_srtp(struct menc_st *st, const char *suite)
+static enum srtp_suite resolve_suite(const char *suite)
{
- crypto_policy_t policy;
- err_status_t e;
+ if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_32))
+ return SRTP_AES_CM_128_HMAC_SHA1_32;
+ if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_80))
+ return SRTP_AES_CM_128_HMAC_SHA1_80;
+
+ return -1;
+}
- if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_32)) {
- crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy);
- }
- else if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_80)) {
- crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy);
- }
- else {
- warning("srtp: unknown SRTP crypto suite (%s)\n", suite);
- return ENOENT;
- }
- /* transmit policy */
- st->policy_tx.rtp = policy;
- st->policy_tx.rtcp = policy;
- st->policy_tx.ssrc.type = ssrc_any_outbound;
- st->policy_tx.key = st->key_tx;
- st->policy_tx.next = NULL;
+static int start_srtp(struct menc_st *st, const char *suite_name)
+{
+ enum srtp_suite suite;
+ int err;
- /* receive policy */
- st->policy_rx.rtp = policy;
- st->policy_rx.rtcp = policy;
- st->policy_rx.ssrc.type = ssrc_any_inbound;
- st->policy_rx.key = st->key_rx;
- st->policy_rx.next = NULL;
+ suite = resolve_suite(suite_name);
/* allocate and initialize the SRTP session */
- e = srtp_create(&st->srtp_tx, &st->policy_tx);
- if (e != err_status_ok) {
- warning("srtp: srtp_create TX failed (%H)\n",
- errstatus_print, e);
- return EPROTO;
+ if (!st->srtp_tx) {
+ err = srtp_alloc(&st->srtp_tx, suite, st->key_tx, 30, 0);
+ if (err) {
+ warning("srtp: srtp_alloc TX failed (%m)\n", err);
+ return err;
+ }
}
- e = srtp_create(&st->srtp_rx, &st->policy_rx);
- if (err_status_ok != e) {
- warning("srtp: srtp_create RX failed (%H)\n",
- errstatus_print, e);
- return EPROTO;
+ if (!st->srtp_rx) {
+ err = srtp_alloc(&st->srtp_rx, suite, st->key_rx, 30, 0);
+ if (err) {
+ warning("srtp: srtp_alloc RX failed (%m)\n", err);
+ return err;
+ }
}
/* use SRTP for this stream/session */
@@ -172,56 +140,32 @@ static int start_srtp(struct menc_st *st, const char *suite)
}
-static int setup_srtp(struct menc_st *st)
-{
- err_status_t e;
-
- /* init SRTP */
- e = crypto_get_random(st->key_tx, SRTP_MASTER_KEY_LEN);
- if (err_status_ok != e) {
- warning("srtp: crypto_get_random() failed (%H)\n",
- errstatus_print, e);
- return ENOSYS;
- }
-
- return 0;
-}
-
-
static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
{
struct menc_st *st = arg;
- err_status_t e;
- int len;
+ size_t len = mbuf_get_left(mb);
+ int lerr = 0;
(void)dst;
if (!st->use_srtp || !is_rtp_or_rtcp(mb))
return false;
- len = (int)mbuf_get_left(mb);
-
- if (mbuf_get_space(mb) < ((size_t)len + SRTP_MAX_TRAILER_LEN)) {
- mbuf_resize(mb, mb->pos + len + SRTP_MAX_TRAILER_LEN);
- }
-
if (is_rtcp_packet(mb)) {
- e = srtp_protect_rtcp(st->srtp_tx, mbuf_buf(mb), &len);
+ lerr = srtcp_encrypt(st->srtp_tx, mb);
}
else {
- e = srtp_protect(st->srtp_tx, mbuf_buf(mb), &len);
+ lerr = srtp_encrypt(st->srtp_tx, mb);
}
- if (err_status_ok != e) {
- warning("srtp: send: failed to protect %s-packet"
- " with %d bytes (%H)\n",
- is_rtcp_packet(mb) ? "RTCP" : "RTP",
- len, errstatus_print, e);
- *err = EPROTO;
+ if (lerr) {
+ warning("srtp: failed to encrypt %s-packet"
+ " with %zu bytes (%m)\n",
+ is_rtcp_packet(mb) ? "RTCP" : "RTP",
+ len, lerr);
+ *err = lerr;
return false;
}
- mbuf_set_end(mb, mb->pos + len);
-
return false; /* continue processing */
}
@@ -229,33 +173,29 @@ static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
struct menc_st *st = arg;
- err_status_t e;
- int len;
+ size_t len = mbuf_get_left(mb);
+ int err = 0;
(void)src;
if (!st->use_srtp || !is_rtp_or_rtcp(mb))
return false;
- len = (int)mbuf_get_left(mb);
-
if (is_rtcp_packet(mb)) {
- e = srtp_unprotect_rtcp(st->srtp_rx, mbuf_buf(mb), &len);
+ err = srtcp_decrypt(st->srtp_rx, mb);
+ if (err) {
+ warning("srtp: failed to decrypt RTCP packet"
+ " with %zu bytes (%m)\n", len, err);
+ }
}
else {
- e = srtp_unprotect(st->srtp_rx, mbuf_buf(mb), &len);
- }
-
- if (e != err_status_ok) {
- warning("srtp: recv: failed to unprotect %s-packet"
- " with %d bytes (%H)\n",
- is_rtcp_packet(mb) ? "RTCP" : "RTP",
- len, errstatus_print, e);
- return true; /* error - drop packet */
+ err = srtp_decrypt(st->srtp_rx, mb);
+ if (err) {
+ warning("srtp: failed to decrypt RTP packet"
+ " with %zu bytes (%m)\n", len, err);
+ }
}
- mbuf_set_end(mb, mb->pos + len);
-
- return false; /* continue processing */
+ return err ? true : false;
}
@@ -381,13 +321,11 @@ static int alloc(struct menc_media **stp, struct menc_sess *sess,
goto out;
/* set our preferred crypto-suite */
- err |= str_dup(&st->crypto_suite, aes_cm_128_hmac_sha1_80);
+ err |= str_dup(&st->crypto_suite, preferred_suite);
if (err)
goto out;
- err = setup_srtp(st);
- if (err)
- goto out;
+ rand_bytes(st->key_tx, SRTP_MASTER_KEY_LEN);
}
/* SDP handling */
@@ -430,15 +368,6 @@ static struct menc menc_srtp_mandf = {
static int mod_srtp_init(void)
{
- err_status_t err;
-
- err = srtp_init();
- if (err_status_ok != err) {
- warning("srtp: srtp_init() failed (%H)\n",
- errstatus_print, err);
- return ENOSYS;
- }
-
menc_register(&menc_srtp_opt);
menc_register(&menc_srtp_mand);
menc_register(&menc_srtp_mandf);
@@ -453,8 +382,6 @@ static int mod_srtp_close(void)
menc_unregister(&menc_srtp_mand);
menc_unregister(&menc_srtp_opt);
- crypto_kernel_shutdown();
-
return 0;
}