diff --git a/daemon/crypto.c b/daemon/crypto.c index f3922178a..75f4651e6 100644 --- a/daemon/crypto.c +++ b/daemon/crypto.c @@ -28,16 +28,14 @@ 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_cm_session_key_init_128(struct crypto_context *c); -static int aes_cm_session_key_init_192(struct crypto_context *c); -static int aes_cm_session_key_init_256(struct crypto_context *c); +static int aes_cm_session_key_init(struct crypto_context *c); static int aes_f8_session_key_init(struct crypto_context *c); static int evp_session_key_cleanup(struct crypto_context *c); static int null_crypt_rtp(struct crypto_context *c, struct rtp_header *r, str *s, u_int64_t idx); static int null_crypt_rtcp(struct crypto_context *c, struct rtcp_packet *r, str *s, u_int64_t idx); /* all lengths are in bytes */ -const struct crypto_suite crypto_suites[] = { +struct crypto_suite __crypto_suites[] = { { .name = "AES_CM_128_HMAC_SHA1_80", .dtls_name = "SRTP_AES128_CM_SHA1_80", @@ -59,7 +57,7 @@ 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_cm_session_key_init_128, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -83,7 +81,7 @@ 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_cm_session_key_init_128, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -107,7 +105,7 @@ 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_cm_session_key_init_192, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -131,7 +129,7 @@ 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_cm_session_key_init_192, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -155,7 +153,7 @@ 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_cm_session_key_init_256, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -179,7 +177,7 @@ 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_cm_session_key_init_256, + .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, { @@ -278,7 +276,8 @@ const struct crypto_suite crypto_suites[] = { }, }; -const int num_crypto_suites = G_N_ELEMENTS(crypto_suites); +const struct crypto_suite *crypto_suites = __crypto_suites; +const int num_crypto_suites = G_N_ELEMENTS(__crypto_suites); @@ -357,11 +356,12 @@ done: ; } -static void aes_ctr_no_ctx(unsigned char *out, str *in, const unsigned char *key, int keylen, const unsigned char *iv) { +static void aes_ctr_no_ctx(unsigned char *out, str *in, const unsigned char *key, const EVP_CIPHER *ciph, + const unsigned char *iv) +{ EVP_CIPHER_CTX *ctx; unsigned char block[16]; int len; - const EVP_CIPHER *ecb_cipher; #if OPENSSL_VERSION_NUMBER >= 0x10100000L ctx = EVP_CIPHER_CTX_new(); @@ -370,22 +370,7 @@ static void aes_ctr_no_ctx(unsigned char *out, str *in, const unsigned char *key ctx = &ctx_s; EVP_CIPHER_CTX_init(ctx); #endif - switch(keylen) { - case 16: - ecb_cipher = EVP_aes_128_ecb(); - break; - case 24: - ecb_cipher = EVP_aes_192_ecb(); - break; - case 32: - ecb_cipher = EVP_aes_256_ecb(); - break; - default: - // silence -Wmaybe-unintialized; must not end up here - assert(FALSE); - break; - } - EVP_EncryptInit_ex(ctx, ecb_cipher, NULL, key, NULL); + EVP_EncryptInit_ex(ctx, ciph, NULL, key, NULL); aes_ctr(out, in, ctx, iv); EVP_EncryptFinal_ex(ctx, block, &len); @@ -401,7 +386,7 @@ static void aes_ctr_no_ctx(unsigned char *out, str *in, const unsigned char *key * x: 112 bits * n <= 256 * out->len := n / 8 */ -static void prf_n(str *out, const unsigned char *key, int keylen, const unsigned char *x) { +static void prf_n(str *out, const unsigned char *key, const EVP_CIPHER *ciph, const unsigned char *x) { unsigned char iv[16]; unsigned char o[32]; unsigned char in[32]; @@ -414,7 +399,7 @@ static void prf_n(str *out, const unsigned char *key, int keylen, const unsigned /* iv[14] = iv[15] = 0; := x << 16 */ ZERO(in); /* outputs the key stream */ str_init_len(&in_s, (void *) in, out->len > 16 ? 32 : 16); - aes_ctr_no_ctx(o, &in_s, key, keylen, iv); + aes_ctr_no_ctx(o, &in_s, key, ciph, iv); memcpy(out->s, o, out->len); } @@ -436,7 +421,7 @@ int crypto_gen_session_key(struct crypto_context *c, str *out, unsigned char lab for (i = 13 - index_len; i < 14; i++) x[i] = key_id[i - (13 - index_len)] ^ x[i]; - prf_n(out, c->params.master_key, c->params.crypto_suite->master_key_len, x); + prf_n(out, c->params.master_key, c->params.crypto_suite->lib_cipher_ptr, x); #if CRYPTO_DEBUG ilog(LOG_DEBUG, "Generated session key: master key " @@ -629,35 +614,7 @@ static int hmac_sha1_rtcp(struct crypto_context *c, char *out, str *in) { return 0; } -static int aes_cm_session_key_init_128(struct crypto_context *c) { - evp_session_key_cleanup(c); - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - c->session_key_ctx[0] = EVP_CIPHER_CTX_new(); -#else - c->session_key_ctx[0] = g_slice_alloc(sizeof(EVP_CIPHER_CTX)); - EVP_CIPHER_CTX_init(c->session_key_ctx[0]); -#endif - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_128_ecb(), NULL, - (unsigned char *) c->session_key, NULL); - return 0; -} - -static int aes_cm_session_key_init_192(struct crypto_context *c) { - evp_session_key_cleanup(c); - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - c->session_key_ctx[0] = EVP_CIPHER_CTX_new(); -#else - c->session_key_ctx[0] = g_slice_alloc(sizeof(EVP_CIPHER_CTX)); - EVP_CIPHER_CTX_init(c->session_key_ctx[0]); -#endif - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_192_ecb(), NULL, - (unsigned char *) c->session_key, NULL); - return 0; -} - -static int aes_cm_session_key_init_256(struct crypto_context *c) { +static int aes_cm_session_key_init(struct crypto_context *c) { evp_session_key_cleanup(c); #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -666,7 +623,7 @@ static int aes_cm_session_key_init_256(struct crypto_context *c) { c->session_key_ctx[0] = g_slice_alloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(c->session_key_ctx[0]); #endif - EVP_EncryptInit_ex(c->session_key_ctx[0], EVP_aes_256_ecb(), NULL, + EVP_EncryptInit_ex(c->session_key_ctx[0], c->params.crypto_suite->lib_cipher_ptr, NULL, (unsigned char *) c->session_key, NULL); return 0; } @@ -677,7 +634,7 @@ static int aes_f8_session_key_init(struct crypto_context *c) { int k_e_len, k_s_len; /* n_e, n_s */ unsigned char *key; - aes_cm_session_key_init_128(c); + aes_cm_session_key_init(c); k_e_len = c->params.crypto_suite->session_key_len; k_s_len = c->params.crypto_suite->session_salt_len; @@ -751,3 +708,21 @@ void crypto_dump_keys(struct crypto_context *in, struct crypto_context *out) { ilog(LOG_DEBUG, "SRTP keys, outgoing:"); dump_key(out); } + +void crypto_init_main() { + struct crypto_suite *cs; + for (int i = 0; i < num_crypto_suites; i++) { + cs = &__crypto_suites[i]; + switch(cs->master_key_len) { + case 16: + cs->lib_cipher_ptr = EVP_aes_128_ecb(); + break; + case 24: + cs->lib_cipher_ptr = EVP_aes_192_ecb(); + break; + case 32: + cs->lib_cipher_ptr = EVP_aes_256_ecb(); + break; + } + } +} diff --git a/daemon/crypto.h b/daemon/crypto.h index 0095697f9..de97ff436 100644 --- a/daemon/crypto.h +++ b/daemon/crypto.h @@ -56,6 +56,7 @@ struct crypto_suite { session_key_init_func session_key_init; session_key_cleanup_func session_key_cleanup; const char *dtls_profile_code; + const void *lib_cipher_ptr; }; struct crypto_session_params { @@ -97,11 +98,13 @@ struct rtp_ssrc_entry { u_int64_t index; }; -extern const struct crypto_suite crypto_suites[]; +extern const struct crypto_suite *crypto_suites; extern const int num_crypto_suites; +void crypto_init_main(); + const struct crypto_suite *crypto_find_suite(const str *); int crypto_gen_session_key(struct crypto_context *, str *, unsigned char, int); void crypto_dump_keys(struct crypto_context *in, struct crypto_context *out); diff --git a/daemon/main.c b/daemon/main.c index 310263304..05322dd45 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -514,6 +514,7 @@ static void init_everything() { sdp_init(); dtls_init(); ice_init(); + crypto_init_main(); interfaces_init(&interfaces); } diff --git a/kernel-module/xt_RTPENGINE.c b/kernel-module/xt_RTPENGINE.c index 4c96a2fd3..0841d55f4 100644 --- a/kernel-module/xt_RTPENGINE.c +++ b/kernel-module/xt_RTPENGINE.c @@ -1651,7 +1651,7 @@ static int validate_srtp(struct rtpengine_srtp *s) { /* XXX shared code */ -static void aes_ctr_128(unsigned char *out, const unsigned char *in, int in_len, +static void aes_ctr(unsigned char *out, const unsigned char *in, int in_len, struct crypto_cipher *tfm, const unsigned char *iv) { unsigned char ivx[16]; @@ -1770,7 +1770,7 @@ static int aes_ctr_128_no_ctx(unsigned char *out, const char *in, int in_len, return PTR_ERR(tfm); crypto_cipher_setkey(tfm, key, key_len); - aes_ctr_128(out, in, in_len, tfm, iv); + aes_ctr(out, in, in_len, tfm, iv); crypto_free_cipher(tfm); return 0; @@ -3563,7 +3563,7 @@ static int srtp_encrypt_aes_cm(struct re_crypto_context *c, ivi[2] ^= idxh; ivi[3] ^= idxl; - aes_ctr_128(r->payload, r->payload, r->payload_len, c->tfm[0], iv); + aes_ctr(r->payload, r->payload, r->payload_len, c->tfm[0], iv); return 0; }