static int 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)
{
	uint8_t k_e[MAX_KEYLEN], k_a[SHA_DIGEST_LENGTH];
	int err = 0;

	if (key_b > sizeof(k_e))
		return EINVAL;

	if (tag_len > SHA_DIGEST_LENGTH)
		return EINVAL;

	c->tag_len = tag_len;

	err |= srtp_derive(k_e, key_b,       0x00+offs, key, key_b, s, s_b);
	err |= srtp_derive(k_a, sizeof(k_a), 0x01+offs, key, key_b, s, s_b);
	err |= srtp_derive(c->k_s.u8, 14,    0x02+offs, key, key_b, s, s_b);
	if (err)
		return err;

	if (encrypted) {
		err = aes_alloc(&c->aes, AES_MODE_CTR, k_e, key_b*8, NULL);
		if (err)
			return err;
	}

	err = hmac_create(&c->hmac, HMAC_HASH_SHA1, k_a, sizeof(k_a));
	if (err)
		return err;

	return err;
}
示例#2
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;

}