implement aes-f8 mode encryption and decryption

git.mgm/mediaproxy-ng/github/master
Richard Fuchs 13 years ago
parent 3c9daae60d
commit 6c84ee466a

@ -21,6 +21,8 @@ static int aes_cm_encrypt_rtp(struct crypto_context *, struct rtp_header *, str
static int aes_cm_encrypt_rtcp(struct crypto_context *, struct rtcp_packet *, str *, u_int64_t);
static int hmac_sha1_rtp(struct crypto_context *, char *out, str *in, u_int64_t);
static int hmac_sha1_rtcp(struct crypto_context *, char *out, str *in);
static int aes_f8_encrypt_rtp(struct crypto_context *c, struct rtp_header *r, str *s, u_int64_t idx);
static int aes_f8_encrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, str *s, u_int64_t idx);
/* all lengths are in bits, some code assumes everything to be multiples of 8 */
const struct crypto_suite crypto_suites[] = {
@ -83,6 +85,10 @@ const struct crypto_suite crypto_suites[] = {
.srtcp_auth_tag = 80,
.srtp_auth_key_len = 160,
.srtcp_auth_key_len = 160,
.encrypt_rtp = aes_f8_encrypt_rtp,
.decrypt_rtp = aes_f8_encrypt_rtp,
.encrypt_rtcp = aes_f8_encrypt_rtcp,
.decrypt_rtcp = aes_f8_encrypt_rtcp,
.hash_rtp = hmac_sha1_rtp,
.hash_rtcp = hmac_sha1_rtcp,
},
@ -262,6 +268,108 @@ static int aes_cm_encrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r,
return aes_cm_encrypt(c, r->ssrc, s, idx);
}
/* rfc 3711 sections 4.1.2 and 4.1.2.1
* encrypts in place */
static void aes_128_f8_encrypt(struct crypto_context *c, unsigned char *iv, str *s) {
EVP_CIPHER_CTX ecc;
unsigned char key_block[16], last_key_block[16], /* S(j), S(j-1) */
ivx[16], /* IV' */
m[16],
x[16];
int i, outlen, left;
int k_e_len, k_s_len; /* n_e, n_s */
u_int32_t j;
unsigned char *p, *key;
k_e_len = c->crypto_suite->session_key_len / 8;
k_s_len = c->crypto_suite->session_salt_len / 8;
key = (unsigned char *) c->session_key;
/* m = k_s || 0x555..5 */
memcpy(m, c->session_salt, k_s_len);
for (i = k_s_len; i < k_e_len; i++)
m[i] = 0x55;
/* IV' = E(k_e XOR m, IV) */
for (i = 0; i < k_e_len; i++)
m[i] ^= key[i];
EVP_CIPHER_CTX_init(&ecc);
EVP_EncryptInit_ex(&ecc, EVP_aes_128_ecb(), NULL, m, NULL);
EVP_EncryptUpdate(&ecc, ivx, &outlen, iv, 16);
assert(outlen == 16);
EVP_EncryptFinal_ex(&ecc, key_block, &outlen);
EVP_CIPHER_CTX_cleanup(&ecc);
p = (unsigned char *) s->s;
left = s->len;
j = 0;
ZERO(last_key_block);
EVP_CIPHER_CTX_init(&ecc);
EVP_EncryptInit_ex(&ecc, EVP_aes_128_ecb(), NULL, (unsigned char *) c->session_key, NULL);
while (left) {
/* S(j) = E(k_e, IV' XOR j XOR S(j-1)) */
memcpy(x, ivx, 16);
x[12] ^= ((j >> 24) & 0xff);
x[13] ^= ((j >> 16) & 0xff);
x[14] ^= ((j >> 8) & 0xff);
x[15] ^= ((j >> 0) & 0xff);
for (i = 0; i < 16; i++)
x[i] ^= last_key_block[i];
EVP_EncryptUpdate(&ecc, key_block, &outlen, x, 16);
assert(outlen == 16);
for (i = 0; i < 16; i++) {
*p ^= key_block[i];
p++;
left--;
if (!left)
goto done;
}
j++;
memcpy(last_key_block, key_block, 16);
}
done:
EVP_EncryptFinal_ex(&ecc, key_block, &outlen);
EVP_CIPHER_CTX_cleanup(&ecc);
}
/* rfc 3711 section 4.1.2.2 */
static int aes_f8_encrypt_rtp(struct crypto_context *c, struct rtp_header *r, str *s, u_int64_t idx) {
unsigned char iv[16];
u_int32_t roc;
iv[0] = '\0';
memcpy(&iv[1], &r->m_pt, 11); /* m, pt, seq, ts, ssrc */
roc = htonl((idx & 0xffffffff0000ULL) >> 16);
memcpy(&iv[12], &roc, sizeof(roc));
aes_128_f8_encrypt(c, iv, s);
return 0;
}
/* rfc 3711 section 4.1.2.3 */
static int aes_f8_encrypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, str *s, u_int64_t idx) {
unsigned char iv[16];
u_int32_t i;
memset(iv, 0, 4);
i = htonl(0x80000000ULL | idx);
memcpy(&iv[4], &i, 4);
memcpy(&iv[8], &r->header.v_p_x, 8); /* v, p, rc, pt, length, ssrc */
aes_128_f8_encrypt(c, iv, s);
return 0;
}
/* rfc 3711, sections 4.2 and 4.2.1 */
static int hmac_sha1_rtp(struct crypto_context *c, char *out, str *in, u_int64_t index) {
unsigned char hmac[20];

Loading…
Cancel
Save