[Build-System] Update libsrtp to 2.4.0

This commit is contained in:
Andrey Volk
2021-08-28 14:19:05 +03:00
parent 641fcd2b26
commit bddff9a2f1
95 changed files with 5998 additions and 3870 deletions

View File

@@ -83,23 +83,76 @@
#define MAX_KEY_LEN 96
#define MAX_FILTER 256
#define MAX_FILE 255
struct srtp_crypto_suite {
const char *can_name;
int gcm_on;
int key_size;
int tag_size;
};
static struct srtp_crypto_suite srtp_crypto_suites[] = {
{.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
#if 0
{.can_name = "F8_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4},
{.can_name = "F8_128_HMAC_SHA1_32", .gcm_on = 0, .key_size = 128, .tag_size = 4},
#endif
{.can_name = "AES_CM_128_HMAC_SHA1_32", .key_size = 128, .tag_size = 4 },
{.can_name = "AES_CM_128_HMAC_SHA1_80", .key_size = 128, .tag_size = 10 },
{.can_name = "AES_CM_128_HMAC_SHA1_32",
.gcm_on = 0,
.key_size = 128,
.tag_size = 4 },
{.can_name = "AES_CM_128_HMAC_SHA1_80",
.gcm_on = 0,
.key_size = 128,
.tag_size = 10 },
{.can_name = "AES_192_CM_HMAC_SHA1_32",
.gcm_on = 0,
.key_size = 192,
.tag_size = 4 },
{.can_name = "AES_192_CM_HMAC_SHA1_80",
.gcm_on = 0,
.key_size = 192,
.tag_size = 10 },
{.can_name = "AES_256_CM_HMAC_SHA1_32",
.gcm_on = 0,
.key_size = 256,
.tag_size = 4 },
{.can_name = "AES_256_CM_HMAC_SHA1_80",
.gcm_on = 0,
.key_size = 256,
.tag_size = 10 },
{.can_name = "AEAD_AES_128_GCM",
.gcm_on = 1,
.key_size = 128,
.tag_size = 16 },
{.can_name = "AEAD_AES_256_GCM",
.gcm_on = 1,
.key_size = 256,
.tag_size = 16 },
{.can_name = NULL }
};
void rtp_decoder_srtp_log_handler(srtp_log_level_t level,
const char *msg,
void *data)
{
char level_char = '?';
switch (level) {
case srtp_log_level_error:
level_char = 'e';
break;
case srtp_log_level_warning:
level_char = 'w';
break;
case srtp_log_level_info:
level_char = 'i';
break;
case srtp_log_level_debug:
level_char = 'd';
break;
}
fprintf(stderr, "SRTP-LOG [%c]: %s\n", level_char, msg);
}
int main(int argc, char *argv[])
{
char errbuf[PCAP_ERRBUF_SIZE];
@@ -112,15 +165,18 @@ int main(int argc, char *argv[])
int c;
struct srtp_crypto_suite scs, *i_scsp;
scs.key_size = 128;
scs.tag_size = 8;
scs.tag_size = 0;
int gcm_on = 0;
char *input_key = NULL;
int b64_input = 0;
char key[MAX_KEY_LEN];
struct bpf_program fp;
char filter_exp[MAX_FILTER] = "";
char pcap_file[MAX_FILE] = "-";
int rtp_packet_offset = DEFAULT_RTP_OFFSET;
rtp_decoder_t dec;
srtp_policy_t policy;
srtp_policy_t policy = { { 0 } };
rtp_decoder_mode_t mode = mode_rtp;
srtp_err_status_t status;
int len;
int expected_len;
@@ -138,9 +194,15 @@ int main(int argc, char *argv[])
exit(1);
}
status = srtp_install_log_handler(rtp_decoder_srtp_log_handler, NULL);
if (status) {
fprintf(stderr, "error: install log handler failed\n");
exit(1);
}
/* check args */
while (1) {
c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:");
c = getopt_s(argc, argv, "b:k:gt:ae:ld:f:s:m:p:o:");
if (c == -1) {
break;
}
@@ -153,10 +215,12 @@ int main(int argc, char *argv[])
break;
case 'e':
scs.key_size = atoi(optarg_s);
if (scs.key_size != 128 && scs.key_size != 256) {
fprintf(stderr,
"error: encryption key size must be 128 or 256 (%d)\n",
scs.key_size);
if (scs.key_size != 128 && scs.key_size != 192 &&
scs.key_size != 256) {
fprintf(
stderr,
"error: encryption key size must be 128, 192 or 256 (%d)\n",
scs.key_size);
exit(1);
}
input_key = malloc(scs.key_size);
@@ -173,7 +237,7 @@ int main(int argc, char *argv[])
sec_servs |= sec_serv_auth;
break;
case 'd':
status = srtp_crypto_kernel_set_debug_module(optarg_s, 1);
status = srtp_set_debug_module(optarg_s, 1);
if (status) {
fprintf(stderr, "error: set debug module (%s) failed\n",
optarg_s);
@@ -207,20 +271,59 @@ int main(int argc, char *argv[])
scs = *i_scsp;
input_key = malloc(scs.key_size);
sec_servs |= sec_serv_conf | sec_serv_auth;
gcm_on = scs.gcm_on;
break;
case 'm':
if (strcasecmp("rtp", optarg_s) == 0) {
mode = mode_rtp;
} else if (strcasecmp("rtcp", optarg_s) == 0) {
mode = mode_rtcp;
} else if (strcasecmp("rtcp-mux", optarg_s) == 0) {
mode = mode_rtcp_mux;
} else {
fprintf(stderr, "Unknown/unsupported mode %s\n", optarg_s);
exit(1);
}
break;
case 'p':
if (strlen(optarg_s) > MAX_FILE) {
fprintf(stderr,
"error: pcap file path bigger than %d characters\n",
MAX_FILE);
exit(1);
}
strcpy(pcap_file, optarg_s);
break;
case 'o':
rtp_packet_offset = atoi(optarg_s);
break;
default:
usage(argv[0]);
}
}
if (scs.tag_size == 0) {
if (gcm_on) {
scs.tag_size = 16;
} else {
scs.tag_size = 10;
}
}
if (gcm_on && scs.tag_size != 8 && scs.tag_size != 16) {
fprintf(stderr, "error: GCM tag size must be 8 or 16 (%d)\n",
scs.tag_size);
// exit(1);
exit(1);
}
if (!gcm_on && scs.tag_size != 4 && scs.tag_size != 10) {
fprintf(stderr, "error: non GCM tag size must be 4 or 10 (%d)\n",
scs.tag_size);
exit(1);
}
if (do_list_mods) {
status = srtp_crypto_kernel_list_debug_modules();
status = srtp_list_debug_modules();
if (status) {
fprintf(stderr, "error: list of debug modules failed\n");
exit(1);
@@ -266,12 +369,24 @@ int main(int argc, char *argv[])
#ifdef OPENSSL
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
if (scs.tag_size == 16) {
srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_16_auth(
&policy.rtcp);
} else {
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_128_8_auth(&policy.rtcp);
}
break;
case 256:
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
if (scs.tag_size == 16) {
srtp_crypto_policy_set_aes_gcm_256_16_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_16_auth(
&policy.rtcp);
} else {
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtp);
srtp_crypto_policy_set_aes_gcm_256_8_auth(&policy.rtcp);
}
break;
}
#else
@@ -282,12 +397,51 @@ int main(int argc, char *argv[])
} else {
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_rtp_default(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
if (scs.tag_size == 4) {
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_32(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
&policy.rtcp);
} else {
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
&policy.rtcp);
}
break;
case 192:
#ifdef OPENSSL
if (scs.tag_size == 4) {
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
&policy.rtcp);
} else {
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
&policy.rtcp);
}
#else
fprintf(stderr,
"error: AES 192 mode only supported when using the "
"OpenSSL crypto engine.\n");
return 0;
#endif
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
if (scs.tag_size == 4) {
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_32(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
&policy.rtcp);
} else {
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
&policy.rtp);
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
&policy.rtcp);
}
break;
}
}
@@ -302,11 +456,26 @@ int main(int argc, char *argv[])
switch (scs.key_size) {
case 128:
srtp_crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(
&policy.rtcp);
break;
case 192:
#ifdef OPENSSL
srtp_crypto_policy_set_aes_cm_192_null_auth(&policy.rtp);
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(
&policy.rtcp);
#else
fprintf(stderr,
"error: AES 192 mode only supported when using the "
"OpenSSL crypto engine.\n");
return 0;
#endif
break;
case 256:
srtp_crypto_policy_set_aes_cm_256_null_auth(&policy.rtp);
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(
&policy.rtcp);
break;
}
}
@@ -342,7 +511,6 @@ int main(int argc, char *argv[])
}
policy.key = (uint8_t *)key;
policy.ekt = NULL;
policy.next = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
@@ -353,7 +521,7 @@ int main(int argc, char *argv[])
policy.rtp.auth_tag_len = scs.tag_size;
if (gcm_on && scs.tag_size != 8) {
fprintf(stderr, "setted tag len %d\n", scs.tag_size);
fprintf(stderr, "set tag len %d\n", scs.tag_size);
policy.rtp.auth_tag_len = scs.tag_size;
}
@@ -365,11 +533,7 @@ int main(int argc, char *argv[])
int pad;
expected_len = policy.rtp.cipher_key_len * 4 / 3;
len = base64_string_to_octet_string(key, &pad, input_key,
expected_len);
if (pad != 0) {
fprintf(stderr, "error: padding in base64 unexpected\n");
exit(1);
}
strlen(input_key));
} else {
expected_len = policy.rtp.cipher_key_len * 2;
len = hex_string_to_octet_string(key, input_key, expected_len);
@@ -388,17 +552,20 @@ int main(int argc, char *argv[])
exit(1);
}
int key_octets = (scs.key_size / 8);
int salt_octets = policy.rtp.cipher_key_len - key_octets;
fprintf(stderr, "set master key/salt to %s/",
octet_string_hex_string(key, 16));
fprintf(stderr, "%s\n", octet_string_hex_string(key + 16, 14));
octet_string_hex_string(key, key_octets));
fprintf(stderr, "%s\n",
octet_string_hex_string(key + key_octets, salt_octets));
} else {
fprintf(stderr,
"error: neither encryption or authentication were selected");
"error: neither encryption or authentication were selected\n");
exit(1);
}
pcap_handle = pcap_open_offline("-", errbuf);
pcap_handle = pcap_open_offline(pcap_file, errbuf);
if (!pcap_handle) {
fprintf(stderr, "libpcap failed to open file '%s'\n", errbuf);
@@ -421,11 +588,22 @@ int main(int argc, char *argv[])
exit(1);
}
fprintf(stderr, "Starting decoder\n");
rtp_decoder_init(dec, policy);
if (rtp_decoder_init(dec, policy, mode, rtp_packet_offset)) {
fprintf(stderr, "error: init failed\n");
exit(1);
}
pcap_loop(pcap_handle, 0, rtp_decoder_handle_pkt, (u_char *)dec);
rtp_decoder_deinit_srtp(dec);
if (dec->mode == mode_rtp || dec->mode == mode_rtcp_mux) {
fprintf(stderr, "RTP packets decoded: %d\n", dec->rtp_cnt);
}
if (dec->mode == mode_rtcp || dec->mode == mode_rtcp_mux) {
fprintf(stderr, "RTCP packets decoded: %d\n", dec->rtcp_cnt);
}
fprintf(stderr, "Packet decode errors: %d\n", dec->error_cnt);
rtp_decoder_deinit(dec);
rtp_decoder_dealloc(dec);
status = srtp_shutdown();
@@ -442,7 +620,8 @@ void usage(char *string)
{
fprintf(
stderr,
"usage: %s [-d <debug>]* [[-k][-b] <key> [-a][-e]]\n"
"usage: %s [-d <debug>]* [[-k][-b] <key>] [-a][-t][-e] [-s "
"<srtp-crypto-suite>] [-m <mode>]\n"
"or %s -l\n"
"where -a use message authentication\n"
" -e <key size> use encryption (use 128 or 256 for key size)\n"
@@ -454,7 +633,10 @@ void usage(char *string)
" -f \"<pcap filter>\" to filter only the desired SRTP packets\n"
" -d <debug> turn on debugging for module <debug>\n"
" -s \"<srtp-crypto-suite>\" to set both key and tag size based\n"
" on RFC4568-style crypto suite specification\n",
" on RFC4568-style crypto suite specification\n"
" -m <mode> set the mode to be one of [rtp]|rtcp|rtcp-mux\n"
" -p <pcap file> path to pcap file (defaults to stdin)\n"
" -o byte offset of RTP packet in capture (defaults to 42)\n",
string, string);
exit(1);
}
@@ -469,27 +651,34 @@ void rtp_decoder_dealloc(rtp_decoder_t rtp_ctx)
free(rtp_ctx);
}
srtp_err_status_t rtp_decoder_init_srtp(rtp_decoder_t decoder,
unsigned int ssrc)
int rtp_decoder_deinit(rtp_decoder_t decoder)
{
decoder->policy.ssrc.value = htonl(ssrc);
return srtp_create(&decoder->srtp_ctx, &decoder->policy);
if (decoder->srtp_ctx) {
return srtp_dealloc(decoder->srtp_ctx);
}
return 0;
}
int rtp_decoder_deinit_srtp(rtp_decoder_t decoder)
int rtp_decoder_init(rtp_decoder_t dcdr,
srtp_policy_t policy,
rtp_decoder_mode_t mode,
int rtp_packet_offset)
{
return srtp_dealloc(decoder->srtp_ctx);
}
int rtp_decoder_init(rtp_decoder_t dcdr, srtp_policy_t policy)
{
dcdr->rtp_offset = DEFAULT_RTP_OFFSET;
dcdr->rtp_offset = rtp_packet_offset;
dcdr->srtp_ctx = NULL;
dcdr->start_tv.tv_usec = 0;
dcdr->start_tv.tv_sec = 0;
dcdr->frame_nr = -1;
dcdr->error_cnt = 0;
dcdr->rtp_cnt = 0;
dcdr->rtcp_cnt = 0;
dcdr->mode = mode;
dcdr->policy = policy;
dcdr->policy.ssrc.type = ssrc_specific;
dcdr->policy.ssrc.type = ssrc_any_inbound;
if (srtp_create(&dcdr->srtp_ctx, &dcdr->policy)) {
return 1;
}
return 0;
}
@@ -516,6 +705,8 @@ void rtp_decoder_handle_pkt(u_char *arg,
const u_char *bytes)
{
rtp_decoder_t dcdr = (rtp_decoder_t)arg;
rtp_msg_t message;
int rtp;
int pktsize;
struct timeval delta;
int octets_recvd;
@@ -531,7 +722,7 @@ void rtp_decoder_handle_pkt(u_char *arg,
}
const void *rtp_packet = bytes + dcdr->rtp_offset;
memcpy((void *)&dcdr->message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
memcpy((void *)&message, rtp_packet, hdr->caplen - dcdr->rtp_offset);
pktsize = hdr->caplen - dcdr->rtp_offset;
octets_recvd = pktsize;
@@ -539,36 +730,41 @@ void rtp_decoder_handle_pkt(u_char *arg,
return;
}
/* verify rtp header */
if (dcdr->message.header.version != 2) {
return;
}
if (dcdr->srtp_ctx == NULL) {
status = rtp_decoder_init_srtp(dcdr, dcdr->message.header.ssrc);
if (status) {
exit(1);
if (dcdr->mode == mode_rtp) {
rtp = 1;
} else if (dcdr->mode == mode_rtcp) {
rtp = 0;
} else {
rtp = 1;
if (octets_recvd >= 2) {
/* rfc5761 */
u_char payload_type = *(bytes + dcdr->rtp_offset + 1) & 0x7f;
rtp = payload_type < 64 || payload_type > 95;
}
}
status = srtp_unprotect(dcdr->srtp_ctx, &dcdr->message, &octets_recvd);
if (status) {
return;
if (rtp) {
/* verify rtp header */
if (message.header.version != 2) {
return;
}
status = srtp_unprotect(dcdr->srtp_ctx, &message, &octets_recvd);
if (status) {
dcdr->error_cnt++;
return;
}
dcdr->rtp_cnt++;
} else {
status = srtp_unprotect_rtcp(dcdr->srtp_ctx, &message, &octets_recvd);
if (status) {
dcdr->error_cnt++;
return;
}
dcdr->rtcp_cnt++;
}
timersub(&hdr->ts, &dcdr->start_tv, &delta);
fprintf(stdout, "%02ld:%02ld.%06ld\n", delta.tv_sec / 60, delta.tv_sec % 60,
(long)delta.tv_usec);
hexdump(&dcdr->message, octets_recvd);
}
void rtp_print_error(srtp_err_status_t status, char *message)
{
// clang-format off
fprintf(stderr,
"error: %s %d%s\n", message, status,
status == srtp_err_status_replay_fail ? " (replay check failed)" :
status == srtp_err_status_bad_param ? " (bad param)" :
status == srtp_err_status_no_ctx ? " (no context)" :
status == srtp_err_status_cipher_fail ? " (cipher failed)" :
status == srtp_err_status_key_expired ? " (key expired)" :
status == srtp_err_status_auth_fail ? " (auth check failed)" : "");
// clang-format on
hexdump(&message, octets_recvd);
}