1 /**
2  * @file srtp.c  Secure Real-time Transport Protocol (SRTP)
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #include <string.h>
7 #include <re_types.h>
8 #include <re_fmt.h>
9 #include <re_mem.h>
10 #include <re_mbuf.h>
11 #include <re_list.h>
12 #include <re_hmac.h>
13 #include <re_sha.h>
14 #include <re_aes.h>
15 #include <re_sa.h>
16 #include <re_rtp.h>
17 #include <re_srtp.h>
18 #include "srtp.h"
19 
20 
21 /** SRTP protocol values */
22 enum {
23 	MAX_KEYLEN  = 32,  /**< Maximum keylength in bytes     */
24 };
25 
26 
seq_diff(uint16_t x,uint16_t y)27 static inline int seq_diff(uint16_t x, uint16_t y)
28 {
29 	return (int)y - (int)x;
30 }
31 
32 
comp_init(struct comp * c,unsigned offs,const uint8_t * key,size_t key_b,const uint8_t * s,size_t s_b,size_t tag_len,bool encrypted,bool hash,enum aes_mode mode)33 static int comp_init(struct comp *c, unsigned offs,
34 		     const uint8_t *key, size_t key_b,
35 		     const uint8_t *s, size_t s_b,
36 		     size_t tag_len, bool encrypted, bool hash,
37 		     enum aes_mode mode)
38 {
39 	uint8_t k_e[MAX_KEYLEN], k_a[SHA_DIGEST_LENGTH];
40 	int err = 0;
41 
42 	if (key_b > sizeof(k_e))
43 		return EINVAL;
44 
45 	if (tag_len > SHA_DIGEST_LENGTH)
46 		return EINVAL;
47 
48 	c->tag_len = tag_len;
49 	c->mode = mode;
50 
51 	err |= srtp_derive(k_e, key_b,       0x00+offs, key, key_b, s, s_b);
52 	err |= srtp_derive(k_a, sizeof(k_a), 0x01+offs, key, key_b, s, s_b);
53 	err |= srtp_derive(c->k_s.u8, 14,    0x02+offs, key, key_b, s, s_b);
54 	if (err)
55 		return err;
56 
57 	if (encrypted) {
58 		err = aes_alloc(&c->aes, mode, k_e, key_b*8, NULL);
59 		if (err)
60 			return err;
61 	}
62 
63 	if (hash) {
64 		err = hmac_create(&c->hmac, HMAC_HASH_SHA1, k_a, sizeof(k_a));
65 		if (err)
66 			return err;
67 	}
68 
69 	return err;
70 }
71 
72 
destructor(void * arg)73 static void destructor(void *arg)
74 {
75 	struct srtp *srtp = arg;
76 
77 	mem_deref(srtp->rtp.aes);
78 	mem_deref(srtp->rtcp.aes);
79 	mem_deref(srtp->rtp.hmac);
80 	mem_deref(srtp->rtcp.hmac);
81 
82 	list_flush(&srtp->streaml);
83 }
84 
85 
srtp_alloc(struct srtp ** srtpp,enum srtp_suite suite,const uint8_t * key,size_t key_bytes,int flags)86 int srtp_alloc(struct srtp **srtpp, enum srtp_suite suite,
87 	       const uint8_t *key, size_t key_bytes, int flags)
88 {
89 	struct srtp *srtp;
90 	const uint8_t *master_salt;
91 	size_t cipher_bytes, salt_bytes, auth_bytes;
92 	enum aes_mode mode;
93 	bool hash;
94 	int err = 0;
95 
96 	if (!srtpp || !key)
97 		return EINVAL;
98 
99 	switch (suite) {
100 
101 	case SRTP_AES_CM_128_HMAC_SHA1_80:
102 		mode         = AES_MODE_CTR;
103 		cipher_bytes = 16;
104 		salt_bytes   = 14;
105 		auth_bytes   = 10;
106 		hash         = true;
107 		break;
108 
109 	case SRTP_AES_CM_128_HMAC_SHA1_32:
110 		mode         = AES_MODE_CTR;
111 		cipher_bytes = 16;
112 		salt_bytes   = 14;
113 		auth_bytes   =  4;
114 		hash         = true;
115 		break;
116 
117 	case SRTP_AES_256_CM_HMAC_SHA1_80:
118 		mode         = AES_MODE_CTR;
119 		cipher_bytes = 32;
120 		salt_bytes   = 14;
121 		auth_bytes   = 10;
122 		hash         = true;
123 		break;
124 
125 	case SRTP_AES_256_CM_HMAC_SHA1_32:
126 		mode         = AES_MODE_CTR;
127 		cipher_bytes = 32;
128 		salt_bytes   = 14;
129 		auth_bytes   =  4;
130 		hash         = true;
131 		break;
132 
133 	case SRTP_AES_128_GCM:
134 		mode         = AES_MODE_GCM;
135 		cipher_bytes = 16;
136 		salt_bytes   = 12;
137 		auth_bytes   = 0;
138 		hash         = false;
139 		break;
140 
141 	case SRTP_AES_256_GCM:
142 		mode         = AES_MODE_GCM;
143 		cipher_bytes = 32;
144 		salt_bytes   = 12;
145 		auth_bytes   = 0;
146 		hash         = false;
147 		break;
148 
149 	default:
150 		return ENOTSUP;
151 	};
152 
153 	if ((cipher_bytes + salt_bytes) != key_bytes)
154 		return EINVAL;
155 
156 	master_salt = &key[cipher_bytes];
157 
158 	srtp = mem_zalloc(sizeof(*srtp), destructor);
159 	if (!srtp)
160 		return ENOMEM;
161 
162 	err |= comp_init(&srtp->rtp,  0, key, cipher_bytes,
163 			 master_salt, salt_bytes, auth_bytes,
164 			 true, hash, mode);
165 	err |= comp_init(&srtp->rtcp, 3, key, cipher_bytes,
166 			 master_salt, salt_bytes, auth_bytes,
167 			 !(flags & SRTP_UNENCRYPTED_SRTCP), hash, mode);
168 	if (err)
169 		goto out;
170 
171  out:
172 	if (err)
173 		mem_deref(srtp);
174 	else
175 		*srtpp = srtp;
176 
177 	return err;
178 }
179 
180 
srtp_encrypt(struct srtp * srtp,struct mbuf * mb)181 int srtp_encrypt(struct srtp *srtp, struct mbuf *mb)
182 {
183 	struct srtp_stream *strm;
184 	struct rtp_header hdr;
185 	struct comp *comp;
186 	size_t start;
187 	uint64_t ix;
188 	int err;
189 
190 	if (!srtp || !mb)
191 		return EINVAL;
192 
193 	comp = &srtp->rtp;
194 
195 	start = mb->pos;
196 
197 	err = rtp_hdr_decode(&hdr, mb);
198 	if (err)
199 		return err;
200 
201 	err = stream_get_seq(&strm, srtp, hdr.ssrc, hdr.seq);
202 	if (err)
203 		return err;
204 
205 	/* Roll-Over Counter (ROC) */
206 	if (seq_diff(strm->s_l, hdr.seq) <= -32768) {
207 		strm->roc++;
208 		strm->s_l = 0;
209 	}
210 
211 	ix = 65536ULL * strm->roc + hdr.seq;
212 
213 	if (comp->aes && comp->mode == AES_MODE_CTR) {
214 		union vect128 iv;
215 		uint8_t *p = mbuf_buf(mb);
216 
217 		srtp_iv_calc(&iv, &comp->k_s, strm->ssrc, ix);
218 
219 		aes_set_iv(comp->aes, iv.u8);
220 		err = aes_encr(comp->aes, p, p, mbuf_get_left(mb));
221 		if (err)
222 			return err;
223 	}
224 	else if (comp->aes && comp->mode == AES_MODE_GCM) {
225 		union vect128 iv;
226 		uint8_t *p = mbuf_buf(mb);
227 		uint8_t tag[GCM_TAGLEN];
228 
229 		srtp_iv_calc_gcm(&iv, &comp->k_s, strm->ssrc, ix);
230 
231 		aes_set_iv(comp->aes, iv.u8);
232 
233 		/* The RTP Header is Associated Data */
234 		err = aes_encr(comp->aes, NULL, &mb->buf[start],
235 			       mb->pos - start);
236 		if (err)
237 			return err;
238 
239 		err = aes_encr(comp->aes, p, p, mbuf_get_left(mb));
240 		if (err)
241 			return err;
242 
243 		err = aes_get_authtag(comp->aes, tag, sizeof(tag));
244 		if (err)
245 			return err;
246 
247 		mb->pos = mb->end;
248 		err = mbuf_write_mem(mb, tag, sizeof(tag));
249 		if (err)
250 			return err;
251 	}
252 
253 	if (comp->hmac) {
254 		const size_t tag_start = mb->end;
255 		uint8_t tag[SHA_DIGEST_LENGTH];
256 
257 		mb->pos = tag_start;
258 
259 		err = mbuf_write_u32(mb, htonl(strm->roc));
260 		if (err)
261 			return err;
262 
263 		mb->pos = start;
264 
265 		err = hmac_digest(comp->hmac, tag, sizeof(tag),
266 				  mbuf_buf(mb), mbuf_get_left(mb));
267 		if (err)
268 			return err;
269 
270 		mb->pos = mb->end = tag_start;
271 
272 		err = mbuf_write_mem(mb, tag, comp->tag_len);
273 		if (err)
274 			return err;
275 	}
276 
277 	if (hdr.seq > strm->s_l)
278 		strm->s_l = hdr.seq;
279 
280 	mb->pos = start;
281 
282 	return 0;
283 }
284 
285 
srtp_decrypt(struct srtp * srtp,struct mbuf * mb)286 int srtp_decrypt(struct srtp *srtp, struct mbuf *mb)
287 {
288 	struct srtp_stream *strm;
289 	struct rtp_header hdr;
290 	struct comp *comp;
291 	uint64_t ix;
292 	size_t start;
293 	int diff;
294 	int err;
295 
296 	if (!srtp || !mb)
297 		return EINVAL;
298 
299 	comp = &srtp->rtp;
300 
301 	start = mb->pos;
302 
303 	err = rtp_hdr_decode(&hdr, mb);
304 	if (err)
305 		return err;
306 
307 	err = stream_get_seq(&strm, srtp, hdr.ssrc, hdr.seq);
308 	if (err)
309 		return err;
310 
311 	diff = seq_diff(strm->s_l, hdr.seq);
312 	if (diff > 32768)
313 		return ETIMEDOUT;
314 
315 	/* Roll-Over Counter (ROC) */
316 	if (diff <= -32768) {
317 		strm->roc++;
318 		strm->s_l = 0;
319 	}
320 
321 	ix = srtp_get_index(strm->roc, strm->s_l, hdr.seq);
322 
323 	if (comp->hmac) {
324 		uint8_t tag_calc[SHA_DIGEST_LENGTH];
325 		uint8_t tag_pkt[SHA_DIGEST_LENGTH];
326 		size_t pld_start, tag_start;
327 
328 		if (mbuf_get_left(mb) < comp->tag_len)
329 			return EBADMSG;
330 
331 		pld_start = mb->pos;
332 		tag_start = mb->end - comp->tag_len;
333 
334 		mb->pos = tag_start;
335 
336 		err = mbuf_read_mem(mb, tag_pkt, comp->tag_len);
337 		if (err)
338 			return err;
339 
340 		mb->pos = mb->end = tag_start;
341 
342 		err = mbuf_write_u32(mb, htonl(strm->roc));
343 		if (err)
344 			return err;
345 
346 		mb->pos = start;
347 
348 		err = hmac_digest(comp->hmac, tag_calc, sizeof(tag_calc),
349 				  mbuf_buf(mb), mbuf_get_left(mb));
350 		if (err)
351 			return err;
352 
353 		mb->pos = pld_start;
354 		mb->end = tag_start;
355 
356 		if (0 != memcmp(tag_calc, tag_pkt, comp->tag_len))
357 			return EAUTH;
358 
359 		/*
360 		 * 3.3.2.  Replay Protection
361 		 *
362 		 * Secure replay protection is only possible when
363 		 * integrity protection is present.
364 		 */
365 		if (!srtp_replay_check(&strm->replay_rtp, ix))
366 			return EALREADY;
367 	}
368 
369 	if (comp->aes && comp->mode == AES_MODE_CTR) {
370 
371 		union vect128 iv;
372 		uint8_t *p = mbuf_buf(mb);
373 
374 		srtp_iv_calc(&iv, &comp->k_s, strm->ssrc, ix);
375 
376 		aes_set_iv(comp->aes, iv.u8);
377 		err = aes_decr(comp->aes, p, p, mbuf_get_left(mb));
378 		if (err)
379 			return err;
380 	}
381 	else if (comp->aes && comp->mode == AES_MODE_GCM) {
382 
383 		union vect128 iv;
384 		uint8_t *p = mbuf_buf(mb);
385 		size_t tag_start;
386 
387 		srtp_iv_calc_gcm(&iv, &comp->k_s, strm->ssrc, ix);
388 
389 		aes_set_iv(comp->aes, iv.u8);
390 
391 		/* The RTP Header is Associated Data */
392 		err = aes_decr(comp->aes, NULL, &mb->buf[start],
393 			       mb->pos - start);
394 		if (err)
395 			return err;
396 
397 		if (mbuf_get_left(mb) < GCM_TAGLEN)
398 			return EBADMSG;
399 
400 		tag_start = mb->end - GCM_TAGLEN;
401 
402 		err = aes_decr(comp->aes, p, p, tag_start - mb->pos);
403 		if (err)
404 			return err;
405 
406 		err = aes_authenticate(comp->aes, &mb->buf[tag_start],
407 				       GCM_TAGLEN);
408 		if (err)
409 			return err;
410 
411 		mb->end = tag_start;
412 
413 		/*
414 		 * 3.3.2.  Replay Protection
415 		 *
416 		 * Secure replay protection is only possible when
417 		 * integrity protection is present.
418 		 */
419 		if (!srtp_replay_check(&strm->replay_rtp, ix))
420 			return EALREADY;
421 
422 	}
423 
424 	if (hdr.seq > strm->s_l)
425 		strm->s_l = hdr.seq;
426 
427 	mb->pos = start;
428 
429 	return 0;
430 }
431