diff --git a/daemon/crypto.c b/daemon/crypto.c index e70949eb7..e75443828 100644 --- a/daemon/crypto.c +++ b/daemon/crypto.c @@ -84,6 +84,102 @@ const struct crypto_suite crypto_suites[] = { .session_key_init = aes_cm_session_key_init, .session_key_cleanup = evp_session_key_cleanup, }, + { + .name = "AES_CM_192_HMAC_SHA1_80", + //.dtls_name = "SRTP_AES128_CM_SHA1_80", + .master_key_len = 24, + .master_salt_len = 14, + .session_key_len = 24, + .session_salt_len = 14, + .srtp_lifetime = 1ULL << 48, + .srtcp_lifetime = 1ULL << 31, + //.kernel_cipher = REC_AES_CM, + //.kernel_hmac = REH_HMAC_SHA1, + .srtp_auth_tag = 10, + .srtcp_auth_tag = 10, + .srtp_auth_key_len = 20, + .srtcp_auth_key_len = 20, + .encrypt_rtp = aes_cm_encrypt_rtp, + .decrypt_rtp = aes_cm_encrypt_rtp, + .encrypt_rtcp = aes_cm_encrypt_rtcp, + .decrypt_rtcp = aes_cm_encrypt_rtcp, + .hash_rtp = hmac_sha1_rtp, + .hash_rtcp = hmac_sha1_rtcp, + .session_key_init = aes_cm_session_key_init, + .session_key_cleanup = evp_session_key_cleanup, + }, + { + .name = "AES_CM_192_HMAC_SHA1_32", + //.dtls_name = "SRTP_AES128_CM_SHA1_32", + .master_key_len = 24, + .master_salt_len = 14, + .session_key_len = 24, + .session_salt_len = 14, + .srtp_lifetime = 1ULL << 48, + .srtcp_lifetime = 1ULL << 31, + //.kernel_cipher = REC_AES_CM, + //.kernel_hmac = REH_HMAC_SHA1, + .srtp_auth_tag = 4, + .srtcp_auth_tag = 10, + .srtp_auth_key_len = 20, + .srtcp_auth_key_len = 20, + .encrypt_rtp = aes_cm_encrypt_rtp, + .decrypt_rtp = aes_cm_encrypt_rtp, + .encrypt_rtcp = aes_cm_encrypt_rtcp, + .decrypt_rtcp = aes_cm_encrypt_rtcp, + .hash_rtp = hmac_sha1_rtp, + .hash_rtcp = hmac_sha1_rtcp, + .session_key_init = aes_cm_session_key_init, + .session_key_cleanup = evp_session_key_cleanup, + }, + { + .name = "AES_CM_256_HMAC_SHA1_80", + //.dtls_name = "SRTP_AES128_CM_SHA1_80", + .master_key_len = 32, + .master_salt_len = 14, + .session_key_len = 32, + .session_salt_len = 14, + .srtp_lifetime = 1ULL << 48, + .srtcp_lifetime = 1ULL << 31, + //.kernel_cipher = REC_AES_CM, + //.kernel_hmac = REH_HMAC_SHA1, + .srtp_auth_tag = 10, + .srtcp_auth_tag = 10, + .srtp_auth_key_len = 20, + .srtcp_auth_key_len = 20, + .encrypt_rtp = aes_cm_encrypt_rtp, + .decrypt_rtp = aes_cm_encrypt_rtp, + .encrypt_rtcp = aes_cm_encrypt_rtcp, + .decrypt_rtcp = aes_cm_encrypt_rtcp, + .hash_rtp = hmac_sha1_rtp, + .hash_rtcp = hmac_sha1_rtcp, + .session_key_init = aes_cm_session_key_init, + .session_key_cleanup = evp_session_key_cleanup, + }, + { + .name = "AES_CM_256_HMAC_SHA1_32", + //.dtls_name = "SRTP_AES128_CM_SHA1_32", + .master_key_len = 32, + .master_salt_len = 14, + .session_key_len = 32, + .session_salt_len = 14, + .srtp_lifetime = 1ULL << 48, + .srtcp_lifetime = 1ULL << 31, + //.kernel_cipher = REC_AES_CM, + //.kernel_hmac = REH_HMAC_SHA1, + .srtp_auth_tag = 4, + .srtcp_auth_tag = 10, + .srtp_auth_key_len = 20, + .srtcp_auth_key_len = 20, + .encrypt_rtp = aes_cm_encrypt_rtp, + .decrypt_rtp = aes_cm_encrypt_rtp, + .encrypt_rtcp = aes_cm_encrypt_rtcp, + .decrypt_rtcp = aes_cm_encrypt_rtcp, + .hash_rtp = hmac_sha1_rtp, + .hash_rtcp = hmac_sha1_rtcp, + .session_key_init = aes_cm_session_key_init, + .session_key_cleanup = evp_session_key_cleanup, + }, { .name = "F8_128_HMAC_SHA1_80", // .dtls_name = "SRTP_AES128_F8_SHA1_80", @@ -259,10 +355,11 @@ done: ; } -static void aes_ctr_128_no_ctx(unsigned char *out, str *in, const unsigned char *key, const unsigned char *iv) { +static void aes_ctr_128_no_ctx(unsigned char *out, str *in, const unsigned char *key, int keylen, const unsigned char *iv) { EVP_CIPHER_CTX *ctx; unsigned char block[16]; int len; + EVP_CIPHER *ecb_cipher; #if OPENSSL_VERSION_NUMBER >= 0x10100000L ctx = EVP_CIPHER_CTX_new(); @@ -271,7 +368,18 @@ static void aes_ctr_128_no_ctx(unsigned char *out, str *in, const unsigned char ctx = &ctx_s; EVP_CIPHER_CTX_init(ctx); #endif - EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, NULL); + 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; + } + EVP_EncryptInit_ex(ctx, ecb_cipher, NULL, key, NULL); aes_ctr_128(out, in, ctx, iv); EVP_EncryptFinal_ex(ctx, block, &len); @@ -287,7 +395,7 @@ static void aes_ctr_128_no_ctx(unsigned char *out, str *in, const unsigned char * x: 112 bits * n <= 256 * out->len := n / 8 */ -static void prf_n(str *out, const unsigned char *key, const unsigned char *x) { +static void prf_n(str *out, const unsigned char *key, int keylen, const unsigned char *x) { unsigned char iv[16]; unsigned char o[32]; unsigned char in[32]; @@ -300,7 +408,7 @@ static void prf_n(str *out, const unsigned char *key, const unsigned char *x) { /* 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_128_no_ctx(o, &in_s, key, iv); + aes_ctr_128_no_ctx(o, &in_s, key, keylen, iv); memcpy(out->s, o, out->len); } @@ -322,7 +430,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, x); + prf_n(out, c->params.master_key, c->params.crypto_suite->master_key_len, x); #if CRYPTO_DEBUG ilog(LOG_DEBUG, "Generated session key: master key " @@ -516,6 +624,7 @@ static int hmac_sha1_rtcp(struct crypto_context *c, char *out, str *in) { } static int aes_cm_session_key_init(struct crypto_context *c) { + EVP_CIPHER * ecb_cipher; evp_session_key_cleanup(c); #if OPENSSL_VERSION_NUMBER >= 0x10100000L @@ -524,7 +633,15 @@ static int aes_cm_session_key_init(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_128_ecb(), NULL, + switch(c->params.crypto_suite->session_key_len) { + case 16: + ecb_cipher = EVP_aes_128_ecb(); + case 24: + ecb_cipher = EVP_aes_192_ecb(); + case 32: + ecb_cipher = EVP_aes_256_ecb(); + } + EVP_EncryptInit_ex(c->session_key_ctx[0], ecb_cipher, NULL, (unsigned char *) c->session_key, NULL); return 0; } diff --git a/daemon/crypto.h b/daemon/crypto.h index b723857f4..0095697f9 100644 --- a/daemon/crypto.h +++ b/daemon/crypto.h @@ -11,9 +11,9 @@ -#define SRTP_MAX_MASTER_KEY_LEN 16 +#define SRTP_MAX_MASTER_KEY_LEN 32 #define SRTP_MAX_MASTER_SALT_LEN 14 -#define SRTP_MAX_SESSION_KEY_LEN 16 +#define SRTP_MAX_SESSION_KEY_LEN 32 #define SRTP_MAX_SESSION_SALT_LEN 14 #define SRTP_MAX_SESSION_AUTH_LEN 20 diff --git a/daemon/sdp.c b/daemon/sdp.c index 22616775a..a8a6f499f 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1,8 +1,8 @@ #include "sdp.h" #include -#include -#include +#include +#include #include #include @@ -274,7 +274,7 @@ INLINE int extract_token(char **sp, char *end, str *out) { *sp = space + 1; } return 0; - + } #define EXTRACT_TOKEN(field) if (extract_token(&start, end, &output->field)) return -1 #define EXTRACT_NETWORK_ADDRESS_NP(field) \ @@ -978,10 +978,10 @@ int sdp_parse(str *body, GQueue *sessions) { if (line_end - value < 4) break; if (!memcmp(value, "RR:", 3)) - *(media ? &media->rr : &session->rr) = + *(media ? &media->rr : &session->rr) = (line_end - value == 4 && value[3] == '0') ? 0 : 1; else if (!memcmp(value, "RS:", 3)) - *(media ? &media->rs : &session->rs) = + *(media ? &media->rs : &session->rs) = (line_end - value == 4 && value[3] == '0') ? 0 : 1; break;