Browse Source

create a dedicated session key context to save some cpu

git.mgm/mediaproxy-ng/github/master
Richard Fuchs 13 years ago
parent
commit
f38fe3f1e0
5 changed files with 68 additions and 12 deletions
  1. +3
    -0
      daemon/call.c
  2. +47
    -12
      daemon/crypto.c
  3. +14
    -0
      daemon/crypto.h
  4. +2
    -0
      daemon/rtcp.c
  5. +2
    -0
      daemon/rtp.c

+ 3
- 0
daemon/call.c View File

@ -1614,6 +1614,9 @@ static void kill_callstream(struct callstream *s) {
if (r->fd.fd != -1)
poller_del_item(s->call->callmaster->poller, r->fd.fd);
crypto_cleanup(&r->crypto.in);
crypto_cleanup(&r->crypto.out);
}
}
}


+ 47
- 12
daemon/crypto.c View File

@ -3,6 +3,7 @@
#include <string.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <glib.h>
#include "str.h"
#include "aux.h"
@ -23,6 +24,8 @@ 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);
static int aes_session_key_init(struct crypto_context *c);
static int aes_session_key_cleanup(struct crypto_context *c);
/* all lengths are in bits, some code assumes everything to be multiples of 8 */
const struct crypto_suite crypto_suites[] = {
@ -47,6 +50,8 @@ const struct crypto_suite crypto_suites[] = {
.decrypt_rtcp = aes_cm_encrypt_rtcp,
.hash_rtp = hmac_sha1_rtp,
.hash_rtcp = hmac_sha1_rtcp,
.session_key_init = aes_session_key_init,
.session_key_cleanup = aes_session_key_cleanup,
},
{
.name = "AES_CM_128_HMAC_SHA1_32",
@ -125,8 +130,7 @@ const struct crypto_suite *crypto_find_suite(const str *s) {
/* rfc 3711 section 4.1 and 4.1.1
* "in" and "out" MAY point to the same buffer */
static void aes_ctr_128(char *out, str *in, char *key, char *iv) {
EVP_CIPHER_CTX ecc;
static void aes_ctr_128(char *out, str *in, EVP_CIPHER_CTX *ecc, char *iv) {
unsigned char ivx[16];
unsigned char key_block[16];
unsigned char *p, *q;
@ -134,19 +138,17 @@ static void aes_ctr_128(char *out, str *in, char *key, char *iv) {
int outlen, i;
u_int64_t *pi, *qi, *ki;
if (!ecc)
return;
memcpy(ivx, iv, 16);
pi = (void *) in->s;
qi = (void *) out;
ki = (void *) key_block;
left = in->len;
/* XXX do this only once per thread or maybe once per stream/key? */
EVP_CIPHER_CTX_init(&ecc);
EVP_EncryptInit_ex(&ecc, EVP_aes_128_ecb(), NULL, (unsigned char *) key, NULL);
while (left) {
EVP_EncryptUpdate(&ecc, key_block, &outlen, ivx, 16);
EVP_EncryptUpdate(ecc, key_block, &outlen, ivx, 16);
assert(outlen == 16);
if (G_UNLIKELY(left < 16)) {
@ -173,10 +175,19 @@ static void aes_ctr_128(char *out, str *in, char *key, char *iv) {
}
done:
;
}
EVP_EncryptFinal_ex(&ecc, key_block, &outlen);
static void aes_ctr_128_no_ctx(char *out, str *in, char *key, char *iv) {
EVP_CIPHER_CTX ctx;
unsigned char block[16];
int len;
EVP_CIPHER_CTX_cleanup(&ecc);
EVP_CIPHER_CTX_init(&ctx);
EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, (unsigned char *) key, NULL);
aes_ctr_128(out, in, &ctx, iv);
EVP_EncryptFinal_ex(&ctx, block, &len);
EVP_CIPHER_CTX_cleanup(&ctx);
}
/* rfc 3711 section 4.3.1 and 4.3.3
@ -197,7 +208,7 @@ static void prf_n(str *out, char *key, char *x) {
/* iv[14] = iv[15] = 0; := x << 16 */
ZERO(in); /* outputs the key stream */
str_init_len(&in_s, in, out->len >= 16 ? 32 : 16);
aes_ctr_128(o, &in_s, key, iv);
aes_ctr_128_no_ctx(o, &in_s, key, iv);
memcpy(out->s, o, out->len);
}
@ -263,7 +274,7 @@ static int aes_cm_encrypt(struct crypto_context *c, u_int32_t ssrc, str *s, u_in
ivi[2] ^= idxh;
ivi[3] ^= idxl;
aes_ctr_128(s->s, s, c->session_key, (char *) iv);
aes_ctr_128(s->s, s, c->session_key_ctx, (char *) iv);
return 0;
}
@ -423,3 +434,27 @@ static int hmac_sha1_rtcp(struct crypto_context *c, char *out, str *in) {
return 0;
}
static int aes_session_key_init(struct crypto_context *c) {
aes_session_key_cleanup(c);
c->session_key_ctx = g_slice_alloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(c->session_key_ctx);
EVP_EncryptInit_ex(c->session_key_ctx, EVP_aes_128_ecb(), NULL,
(unsigned char *) c->session_key, NULL);
return 0;
}
static int aes_session_key_cleanup(struct crypto_context *c) {
unsigned char block[16];
int len;
if (!c->session_key_ctx)
return 0;
EVP_EncryptFinal_ex(c->session_key_ctx, block, &len);
EVP_CIPHER_CTX_cleanup(c->session_key_ctx);
g_slice_free1(sizeof(EVP_CIPHER_CTX), c->session_key_ctx);
c->session_key_ctx = NULL;
return 0;
}

+ 14
- 0
daemon/crypto.h View File

@ -32,6 +32,8 @@ typedef int (*crypto_func_rtp)(struct crypto_context *, struct rtp_header *, str
typedef int (*crypto_func_rtcp)(struct crypto_context *, struct rtcp_packet *, str *, u_int64_t);
typedef int (*hash_func_rtp)(struct crypto_context *, char *out, str *in, u_int64_t);
typedef int (*hash_func_rtcp)(struct crypto_context *, char *out, str *in);
typedef int (*session_key_init_func)(struct crypto_context *);
typedef int (*session_key_cleanup_func)(struct crypto_context *);
struct crypto_suite {
const char *name;
@ -56,6 +58,8 @@ struct crypto_suite {
decrypt_rtcp;
hash_func_rtp hash_rtp;
hash_func_rtcp hash_rtcp;
session_key_init_func session_key_init;
session_key_cleanup_func session_key_cleanup;
};
struct crypto_context {
@ -78,6 +82,8 @@ struct crypto_context {
char session_salt[14]; /* k_s */
char session_auth_key[20];
void *session_key_ctx;
int have_session_key:1;
};
@ -117,6 +123,14 @@ static inline int crypto_decrypt_rtcp(struct crypto_context *c, struct rtcp_pack
{
return c->crypto_suite->decrypt_rtcp(c, rtcp, payload, index);
}
static inline int crypto_init_session_key(struct crypto_context *c) {
return c->crypto_suite->session_key_init(c);
}
static inline void crypto_cleanup(struct crypto_context *c) {
if (!c->crypto_suite)
return;
c->crypto_suite->session_key_cleanup(c);
}


+ 2
- 0
daemon/rtcp.c View File

@ -332,6 +332,8 @@ static inline int check_session_keys(struct crypto_context *c) {
goto error;
c->have_session_key = 1;
crypto_init_session_key(c);
return 0;
error:


+ 2
- 0
daemon/rtp.c View File

@ -30,6 +30,8 @@ static inline int check_session_keys(struct crypto_context *c) {
goto error;
c->have_session_key = 1;
crypto_init_session_key(c);
return 0;
error:


Loading…
Cancel
Save