Ejemplo n.º 1
0
int srtp_derive(uint8_t *out, size_t out_len, uint8_t label,
		const uint8_t *master_key, size_t key_bytes,
		const uint8_t *master_salt, size_t salt_bytes)
{
	uint8_t x[AES_BLOCK_SIZE] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
	static const uint8_t null[AES_BLOCK_SIZE * 2];
	struct aes *aes;
	int err;

	if (!out || !master_key || !master_salt)
		return EINVAL;

	if (out_len > sizeof(null) || salt_bytes > sizeof(x))
		return EINVAL;

	memcpy(x, master_salt, salt_bytes);
	x[7] ^= label;

	/* NOTE: Counter Mode is used for both CTR and GCM */
	err = aes_alloc(&aes, AES_MODE_CTR, master_key, key_bytes*8, x);
	if (err)
		return err;

	err = aes_encr(aes, out, null, out_len);

	mem_deref(aes);

	return err;

}
Ejemplo n.º 2
0
int srtp_encrypt(struct srtp *srtp, struct mbuf *mb)
{
	struct srtp_stream *strm;
	struct rtp_header hdr;
	struct comp *comp;
	size_t start;
	uint64_t ix;
	int err;

	if (!srtp || !mb)
		return EINVAL;

	comp = &srtp->rtp;

	start = mb->pos;

	err = rtp_hdr_decode(&hdr, mb);
	if (err)
		return err;

	err = stream_get_seq(&strm, srtp, hdr.ssrc, hdr.seq);
	if (err)
		return err;

	/* Roll-Over Counter (ROC) */
	if (seq_diff(strm->s_l, hdr.seq) <= -32768) {
		strm->roc++;
		strm->s_l = 0;
	}

	ix = 65536ULL * strm->roc + hdr.seq;

	if (comp->aes) {
		union vect128 iv;
		uint8_t *p = mbuf_buf(mb);

		srtp_iv_calc(&iv, &comp->k_s, strm->ssrc, ix);

		aes_set_iv(comp->aes, iv.u8);
		err = aes_encr(comp->aes, p, p, mbuf_get_left(mb));
		if (err)
			return err;
	}

	if (comp->hmac) {
		const size_t tag_start = mb->end;
		uint8_t tag[SHA_DIGEST_LENGTH];

		mb->pos = tag_start;

		err = mbuf_write_u32(mb, htonl(strm->roc));
		if (err)
			return err;

		mb->pos = start;

		err = hmac_digest(comp->hmac, tag, sizeof(tag),
				  mbuf_buf(mb), mbuf_get_left(mb));
		if (err)
			return err;

		mb->pos = mb->end = tag_start;

		err = mbuf_write_mem(mb, tag, comp->tag_len);
		if (err)
			return err;
	}

	if (hdr.seq > strm->s_l)
		strm->s_l = hdr.seq;

	mb->pos = start;

	return 0;
}