From 9063d2ec901b3c977bae415a8c49fa472121065d Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 5 Nov 2020 04:29:47 +0100 Subject: [PATCH 01/17] WIP --- include/srtp.h | 2 + include/srtp_priv.h | 1 + srtp/srtp.c | 140 +++++++++++++++++++++++++++++++++----------- 3 files changed, 110 insertions(+), 33 deletions(-) diff --git a/include/srtp.h b/include/srtp.h index 572bad6d8..9eda2dbc9 100644 --- a/include/srtp.h +++ b/include/srtp.h @@ -343,6 +343,8 @@ typedef struct srtp_policy_t { int *enc_xtn_hdr; /**< List of header ids to encrypt. */ int enc_xtn_hdr_count; /**< Number of entries in list of header */ /**< ids. */ + unsigned int use_cryptex; /**< Encrypt header block and CSRCS with */ + /**< cryptex. */ struct srtp_policy_t *next; /**< Pointer to next stream policy. */ } srtp_policy_t; diff --git a/include/srtp_priv.h b/include/srtp_priv.h index d449f2a4e..a2126e9d8 100644 --- a/include/srtp_priv.h +++ b/include/srtp_priv.h @@ -151,6 +151,7 @@ typedef struct srtp_stream_ctx_t_ { int *enc_xtn_hdr; int enc_xtn_hdr_count; uint32_t pending_roc; + unsigned int use_cryptex; struct srtp_stream_ctx_t_ *next; /* linked list of streams */ } strp_stream_ctx_t_; diff --git a/srtp/srtp.c b/srtp/srtp.c index 030cc83cd..c79895728 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -174,8 +174,8 @@ srtp_err_status_t srtp_stream_dealloc(srtp_stream_ctx_t *stream, } /* - * deallocate cipher, if it is not the same as that in template - */ + * deallocate cipher, if it is not the same as that in template + */ if (template_session_keys && session_keys->rtp_cipher == template_session_keys->rtp_cipher) { /* do nothing */ @@ -437,6 +437,8 @@ srtp_err_status_t srtp_stream_alloc(srtp_stream_ctx_t **str_ptr, str->enc_xtn_hdr_count = 0; } + str->use_cryptex = p->use_cryptex; + return srtp_err_status_ok; } @@ -547,7 +549,7 @@ srtp_err_status_t srtp_stream_clone(const srtp_stream_ctx_t *stream_template, /* copy information about extensions header encryption */ str->enc_xtn_hdr = stream_template->enc_xtn_hdr; str->enc_xtn_hdr_count = stream_template->enc_xtn_hdr_count; - + str->use_cryptex = stream_template->use_cryptex; /* defensive coding */ str->next = NULL; return srtp_err_status_ok; @@ -878,7 +880,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp, /* If RTP or RTCP have a key length > AES-128, assume matching kdf. */ /* TODO: kdf algorithm, master key length, and master salt length should * be part of srtp_policy_t. - */ + */ session_keys = &srtp->session_keys[current_mki_index]; /* initialize key limit to maximum value */ @@ -1297,8 +1299,8 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp, void srtp_event_reporter(srtp_event_data_t *data) { - srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ", - data->ssrc); + srtp_err_report(srtp_err_level_warning, + "srtp: in stream 0x%x: ", data->ssrc); switch (data->event) { case event_ssrc_collision: @@ -2060,7 +2062,8 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, srtp_session_keys_t *session_keys = NULL; uint8_t *mki_location = NULL; int advance_packet_index = 0; - + int xtn_hdr_length = 0; + int xtn_profile_specific = 0; debug_print0(mod_srtp, "function srtp_protect"); /* we assume the hdr is 32-bit aligned to start */ @@ -2169,10 +2172,29 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, * if we're not providing confidentiality, set enc_start to NULL */ if (stream->rtp_services & sec_serv_conf) { - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + /* Cryptex can only encrypt CSRCS if header extension is present*/ + if (stream->use_cryptex && hdr->cc && !hdr->x) { + return srtp_err_status_parse_err; + } if (hdr->x == 1) { - xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; - enc_start += (ntohs(xtn_hdr->length) + 1); + xtn_hdr = (srtp_hdr_xtnd_t *)(uint32_t *)hdr + + uint32s_in_rtp_header + hdr->cc; + xtn_hdr_length = ntohs(xtn_hdr->length); + xtn_profile_specific = ntohs(xtn_hdr->profile_specific); + } + /* If no header extension is present cyrptex has no effect */ + if (stream->use_cryptex && hdr->x) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header; + if (hdr->cc) { + /* Move CSRCS so it is contiguos with extension header block */ + memmove(enc_start + 1, enc_start, hdr->cc * 4); + } + enc_start++; + } else { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + enc_start += (xtn_hdr_length + 1); + } } /* note: the passed size is without the auth tag */ if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len)) @@ -2319,6 +2341,22 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, (unsigned int *)&enc_octet_len); if (status) return srtp_err_status_cipher_fail; + + if (stream->use_cryptex && xtn_hdr) { + if (hdr->cc) { + /* Restore CSRCS to its original position */ + memmove(enc_start - 1, enc_start, hdr->cc * 4); + } + /* Restore extension header and change profiles by crytex values*/ + xtn_hdr->length = htons(xtn_hdr_length); + if (xtn_profile_specific == 0xbede) { + xtn_hdr->profile_specific = htons(0xc0de); + } else if (xtn_profile_specific == 0x1000) { + xtn_hdr->profile_specific = htons(0xc2de); + } else { + return srtp_err_status_parse_err; + } + } } /* @@ -2390,6 +2428,9 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, int advance_packet_index = 0; uint32_t roc_to_set = 0; uint16_t seq_to_set = 0; + int xtn_hdr_length = 0; + int xtn_profile_specific = 0; + unsigned int use_cryptex = 0; debug_print0(mod_srtp, "function srtp_unprotect"); @@ -2538,29 +2579,6 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, est = be64_to_cpu(est << 16); #endif - /* - * find starting point for decryption and length of data to be - * decrypted - the encrypted portion starts after the rtp header - * extension, if present; otherwise, it starts after the last csrc, - * if any are present - * - * if we're not providing confidentiality, set enc_start to NULL - */ - if (stream->rtp_services & sec_serv_conf) { - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; - if (hdr->x == 1) { - xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; - enc_start += (ntohs(xtn_hdr->length) + 1); - } - if (!((uint8_t *)enc_start <= - (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size))) - return srtp_err_status_parse_err; - enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len - mki_size - - ((uint8_t *)enc_start - (uint8_t *)hdr)); - } else { - enc_start = NULL; - } - /* * if we're providing authentication, set the auth_start and auth_tag * pointers to the proper locations; otherwise, set auth_start to NULL @@ -2622,6 +2640,46 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, return srtp_err_status_auth_fail; } + /* + * find starting point for decryption and length of data to be + * decrypted - the encrypted portion starts after the rtp header + * extension, if present; otherwise, it starts after the last csrc, + * if any are present + * + * if we're not providing confidentiality, set enc_start to NULL + */ + if (stream->rtp_services & sec_serv_conf) { + if (hdr->x == 1) { + xtn_hdr = (srtp_hdr_xtnd_t *)(uint32_t *)hdr + + uint32s_in_rtp_header + hdr->cc; + xtn_hdr_length = ntohs(xtn_hdr->length); + xtn_profile_specific = ntohs(xtn_hdr->profile_specific); + } + + /* Check if the profile is the one for cryptex */ + if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header; + if (hdr->cc) { + /* Move CSRCS so it is contiguos with extension header block */ + memmove(enc_start + 1, enc_start, hdr->cc * 4); + } + enc_start++; + use_cryptex = 1; + } else { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + enc_start += (xtn_hdr_length + 1); + } + } + if (!((uint8_t *)enc_start <= + (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size))) + return srtp_err_status_parse_err; + enc_octet_len = (uint32_t)(*pkt_octet_len - tag_len - mki_size - + ((uint8_t *)enc_start - (uint8_t *)hdr)); + } else { + enc_start = NULL; + } + /* * update the key usage limit, and check it to make sure that we * didn't just hit either the soft limit or the hard limit, and call @@ -2654,6 +2712,22 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, (uint8_t *)enc_start, &enc_octet_len); if (status) return srtp_err_status_cipher_fail; + + if (use_cryptex) { + if (hdr->cc) { + /* Restore CSRCS to its original position */ + memmove(enc_start - 1, enc_start, hdr->cc * 4); + } + /* Restore extension header and change profiles by crytex values*/ + xtn_hdr->length = htons(xtn_hdr_length); + if (xtn_profile_specific == 0xc0de) { + xtn_hdr->profile_specific = htons(0xbede); + } else if (xtn_profile_specific == 0xc2de) { + xtn_hdr->profile_specific = htons(0x1000); + } else { + return srtp_err_status_parse_err; + } + } } /* From 95b0e9735dc32d339fc1e49a42d55cf1dd91fdde Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 5 Nov 2020 04:45:35 +0100 Subject: [PATCH 02/17] replace memmove by for loop --- srtp/srtp.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index c79895728..fac255b33 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -2184,12 +2184,11 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, } /* If no header extension is present cyrptex has no effect */ if (stream->use_cryptex && hdr->x) { - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header; - if (hdr->cc) { - /* Move CSRCS so it is contiguos with extension header block */ - memmove(enc_start + 1, enc_start, hdr->cc * 4); - } - enc_start++; + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Move CSRCS so it is contiguos with extension header block */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i + 1] = csrcs[i]; + enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; if (hdr->x == 1) { @@ -2343,10 +2342,10 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; if (stream->use_cryptex && xtn_hdr) { - if (hdr->cc) { - /* Restore CSRCS to its original position */ - memmove(enc_start - 1, enc_start, hdr->cc * 4); - } + uint32_t* csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Restore CSRCS to its original position */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i+1]; /* Restore extension header and change profiles by crytex values*/ xtn_hdr->length = htons(xtn_hdr_length); if (xtn_profile_specific == 0xbede) { @@ -2658,12 +2657,11 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header; - if (hdr->cc) { - /* Move CSRCS so it is contiguos with extension header block */ - memmove(enc_start + 1, enc_start, hdr->cc * 4); - } - enc_start++; + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Move CSRCS so it is contiguos with extension header block */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i + 1] = csrcs[i]; + enc_start = csrcs + 1; use_cryptex = 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; @@ -2714,10 +2712,10 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; if (use_cryptex) { - if (hdr->cc) { - /* Restore CSRCS to its original position */ - memmove(enc_start - 1, enc_start, hdr->cc * 4); - } + int32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Restore CSRCS to its original position */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i + 1]; /* Restore extension header and change profiles by crytex values*/ xtn_hdr->length = htons(xtn_hdr_length); if (xtn_profile_specific == 0xc0de) { From 62bf7a84ed62c1b7f6562b9a3582bd5bfec41c89 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 5 Nov 2020 22:23:10 +0100 Subject: [PATCH 03/17] cryptex in aead --- srtp/srtp.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index fac255b33..31136ec6a 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1700,6 +1700,8 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, srtp_hdr_xtnd_t *xtn_hdr = NULL; unsigned int mki_size = 0; uint8_t *mki_location = NULL; + int xtn_hdr_length = 0; + int xtn_profile_specific = 0; debug_print0(mod_srtp, "function srtp_protect_aead"); @@ -1729,10 +1731,29 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, * extension, if present; otherwise, it starts after the last csrc, * if any are present */ - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + + /* Cryptex can only encrypt CSRCS if header extension is present*/ + if (stream->use_cryptex && hdr->cc && !hdr->x) { + return srtp_err_status_parse_err; + } if (hdr->x == 1) { - xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; - enc_start += (ntohs(xtn_hdr->length) + 1); + xtn_hdr = (srtp_hdr_xtnd_t *)(uint32_t *)hdr + uint32s_in_rtp_header + + hdr->cc; + xtn_hdr_length = ntohs(xtn_hdr->length); + xtn_profile_specific = ntohs(xtn_hdr->profile_specific); + } + /* If no header extension is present cyrptex has no effect */ + if (stream->use_cryptex && hdr->x) { + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Move CSRCS so it is contiguos with extension header block */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i + 1] = csrcs[i]; + enc_start = csrcs + 1; + } else { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + enc_start += (xtn_hdr_length + 1); + } } /* note: the passed size is without the auth tag */ if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len)) @@ -1814,6 +1835,23 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, if (status) { return srtp_err_status_cipher_fail; } + + if (stream->use_cryptex && xtn_hdr) { + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Restore CSRCS to its original position */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i + 1]; + /* Restore extension header and change profiles by crytex values*/ + xtn_hdr->length = htons(xtn_hdr_length); + if (xtn_profile_specific == 0xbede) { + xtn_hdr->profile_specific = htons(0xc0de); + } else if (xtn_profile_specific == 0x1000) { + xtn_hdr->profile_specific = htons(0xc2de); + } else { + return srtp_err_status_parse_err; + } + } + /* * If we're doing GCM, we need to get the tag * and append that to the output @@ -1861,6 +1899,9 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, int tag_len; unsigned int aad_len; srtp_hdr_xtnd_t *xtn_hdr = NULL; + int xtn_hdr_length = 0; + int xtn_profile_specific = 0; + unsigned int use_cryptex = 0; debug_print0(mod_srtp, "function srtp_unprotect_aead"); @@ -1902,10 +1943,26 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, * extension, if present; otherwise, it starts after the last csrc, * if any are present */ - enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; if (hdr->x == 1) { - xtn_hdr = (srtp_hdr_xtnd_t *)enc_start; - enc_start += (ntohs(xtn_hdr->length) + 1); + xtn_hdr = (srtp_hdr_xtnd_t *)(uint32_t *)hdr + uint32s_in_rtp_header + + hdr->cc; + xtn_hdr_length = ntohs(xtn_hdr->length); + xtn_profile_specific = ntohs(xtn_hdr->profile_specific); + } + + /* Check if the profile is the one for cryptex */ + if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Move CSRCS so it is contiguos with extension header block */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i + 1] = csrcs[i]; + enc_start = csrcs + 1; + use_cryptex = 1; + } else { + enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; + if (hdr->x == 1) { + enc_start += (xtn_hdr_length + 1); + } } if (!((uint8_t *)enc_start <= (uint8_t *)hdr + (*pkt_octet_len - tag_len - mki_size))) @@ -1961,6 +2018,22 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, return status; } + if (use_cryptex) { + int32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Restore CSRCS to its original position */ + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i + 1]; + /* Restore extension header and change profiles by crytex values*/ + xtn_hdr->length = htons(xtn_hdr_length); + if (xtn_profile_specific == 0xc0de) { + xtn_hdr->profile_specific = htons(0xbede); + } else if (xtn_profile_specific == 0xc2de) { + xtn_hdr->profile_specific = htons(0x1000); + } else { + return srtp_err_status_parse_err; + } + } + if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) { /* * extensions header encryption RFC 6904 @@ -2064,6 +2137,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, int advance_packet_index = 0; int xtn_hdr_length = 0; int xtn_profile_specific = 0; + debug_print0(mod_srtp, "function srtp_protect"); /* we assume the hdr is 32-bit aligned to start */ From 4939886d0046d4593bb3359020b062288efe9226 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Thu, 5 Nov 2020 23:16:26 +0100 Subject: [PATCH 04/17] fix csrcs type --- srtp/srtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 31136ec6a..9598da86f 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -2019,7 +2019,7 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, } if (use_cryptex) { - int32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; @@ -2786,7 +2786,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; if (use_cryptex) { - int32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; From e16a8155bd2ae412af99402adaa80c1875463493 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Fri, 6 Nov 2020 22:19:07 +0100 Subject: [PATCH 05/17] cyrptex -> cryptex --- srtp/srtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 9598da86f..9e9a3e2a7 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1742,7 +1742,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, xtn_hdr_length = ntohs(xtn_hdr->length); xtn_profile_specific = ntohs(xtn_hdr->profile_specific); } - /* If no header extension is present cyrptex has no effect */ + /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so it is contiguos with extension header block */ @@ -2256,7 +2256,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, xtn_hdr_length = ntohs(xtn_hdr->length); xtn_profile_specific = ntohs(xtn_hdr->profile_specific); } - /* If no header extension is present cyrptex has no effect */ + /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so it is contiguos with extension header block */ From 664da14497510a64933d760d1de33dc2725f49b7 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Mon, 9 Nov 2020 22:55:00 +0100 Subject: [PATCH 06/17] fix test/srtp_driver structs --- test/srtp_driver.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 133554060..9b5a4bbb6 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -3445,6 +3445,7 @@ const srtp_policy_t default_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3474,6 +3475,7 @@ const srtp_policy_t aes_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3503,6 +3505,7 @@ const srtp_policy_t hmac_only_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3535,6 +3538,7 @@ const srtp_policy_t aes128_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3566,6 +3570,7 @@ const srtp_policy_t aes128_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3597,6 +3602,7 @@ const srtp_policy_t aes256_gcm_8_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3628,6 +3634,7 @@ const srtp_policy_t aes256_gcm_8_cauth_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; #endif @@ -3658,6 +3665,7 @@ const srtp_policy_t null_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3727,6 +3735,7 @@ const srtp_policy_t aes_256_hmac_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3774,6 +3783,7 @@ const srtp_policy_t hmac_only_with_ekt_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; @@ -3801,6 +3811,7 @@ const srtp_policy_t *policy_array[] = { &null_policy, &aes_256_hmac_policy, &hmac_only_with_ekt_policy, + 0, NULL }; // clang-format on @@ -3833,5 +3844,6 @@ const srtp_policy_t wildcard_policy = { 0, /* retransmission not allowed */ NULL, /* no encrypted extension headers */ 0, /* list of encrypted extension headers is empty */ + 0, NULL }; From 3fe608b78761af59d05aa7c79a52be6ce512f5fd Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Tue, 10 Nov 2020 19:37:45 +0100 Subject: [PATCH 07/17] clang-format --- srtp/srtp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 9e9a3e2a7..4f65bf9bd 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1299,8 +1299,8 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp, void srtp_event_reporter(srtp_event_data_t *data) { - srtp_err_report(srtp_err_level_warning, - "srtp: in stream 0x%x: ", data->ssrc); + srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ", + data->ssrc); switch (data->event) { case event_ssrc_collision: @@ -1731,7 +1731,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, * extension, if present; otherwise, it starts after the last csrc, * if any are present */ - + /* Cryptex can only encrypt CSRCS if header extension is present*/ if (stream->use_cryptex && hdr->cc && !hdr->x) { return srtp_err_status_parse_err; @@ -2416,10 +2416,10 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; if (stream->use_cryptex && xtn_hdr) { - uint32_t* csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i] = csrcs[i+1]; + csrcs[i] = csrcs[i + 1]; /* Restore extension header and change profiles by crytex values*/ xtn_hdr->length = htons(xtn_hdr_length); if (xtn_profile_specific == 0xbede) { @@ -2784,7 +2784,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, (uint8_t *)enc_start, &enc_octet_len); if (status) return srtp_err_status_cipher_fail; - + if (use_cryptex) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Restore CSRCS to its original position */ From 696ae825b917f18e9246e6f91f2a1758f1411d4d Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Wed, 11 Nov 2020 01:51:28 +0100 Subject: [PATCH 08/17] remove tabs --- srtp/srtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 4f65bf9bd..d7e5df42e 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1300,7 +1300,7 @@ srtp_err_status_t srtp_stream_init(srtp_stream_ctx_t *srtp, void srtp_event_reporter(srtp_event_data_t *data) { srtp_err_report(srtp_err_level_warning, "srtp: in stream 0x%x: ", - data->ssrc); + data->ssrc); switch (data->event) { case event_ssrc_collision: From 4ab5255fd7a2d41d0cb83908223745d075350271 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Mon, 16 Nov 2020 00:22:03 +0100 Subject: [PATCH 09/17] [wip] --- srtp/srtp.c | 57 +++++---- test/srtp_driver.c | 301 +++++++++++++++++++++++++++++++++++++++++++++ test/util.c | 2 +- 3 files changed, 334 insertions(+), 26 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index d7e5df42e..1262726ab 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1746,9 +1746,18 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, if (stream->use_cryptex && hdr->x) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so it is contiguos with extension header block */ - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i + 1] = csrcs[i]; + for (unsigned char i = hdr->cc; i > 0 ; --i) + csrcs[i] = csrcs[i - 1]; enc_start = csrcs + 1; + /* Change profiles by cryptex values and set it before moved csrcs */ + if (xtn_profile_specific == 0xbede) { + csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); + } else if (xtn_profile_specific == 0x1000) { + csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); + } else { + printf("%x",xtn_profile_specific); + return srtp_err_status_parse_err; + } } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; if (hdr->x == 1) { @@ -1841,15 +1850,6 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; - /* Restore extension header and change profiles by crytex values*/ - xtn_hdr->length = htons(xtn_hdr_length); - if (xtn_profile_specific == 0xbede) { - xtn_hdr->profile_specific = htons(0xc0de); - } else if (xtn_profile_specific == 0x1000) { - xtn_hdr->profile_specific = htons(0xc2de); - } else { - return srtp_err_status_parse_err; - } } /* @@ -1956,6 +1956,14 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Move CSRCS so it is contiguos with extension header block */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i + 1] = csrcs[i]; + /* Change profiles by cryptex values and set it before moved csrcs */ + if (xtn_profile_specific == 0xbede) { + csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); + } else if (xtn_profile_specific == 0x1000) { + csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); + } else { + return srtp_err_status_parse_err; + } enc_start = csrcs + 1; use_cryptex = 1; } else { @@ -2023,7 +2031,7 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; - /* Restore extension header and change profiles by crytex values*/ + /* Restore extension header and change profiles by cryptex values*/ xtn_hdr->length = htons(xtn_hdr_length); if (xtn_profile_specific == 0xc0de) { xtn_hdr->profile_specific = htons(0xbede); @@ -2259,9 +2267,17 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Move CSRCS so it is contiguos with extension header block */ - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i + 1] = csrcs[i]; + /* Move CSRCS so block is contiguous with extension header block */ + for (unsigned char i = hdr->cc; i > 0 ; --i) + csrcs[i] = csrcs[i - 1]; + /* Change profiles by cryptex values and set it before moved csrcs */ + if (xtn_profile_specific == 0xbede) { + csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); + } else if (xtn_profile_specific == 0x1000) { + csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); + } else { + return srtp_err_status_parse_err; + } enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; @@ -2420,15 +2436,6 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; - /* Restore extension header and change profiles by crytex values*/ - xtn_hdr->length = htons(xtn_hdr_length); - if (xtn_profile_specific == 0xbede) { - xtn_hdr->profile_specific = htons(0xc0de); - } else if (xtn_profile_specific == 0x1000) { - xtn_hdr->profile_specific = htons(0xc2de); - } else { - return srtp_err_status_parse_err; - } } } @@ -2790,7 +2797,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Restore CSRCS to its original position */ for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; - /* Restore extension header and change profiles by crytex values*/ + /* Restore extension header and change profiles by cryptex values*/ xtn_hdr->length = htons(xtn_hdr_length); if (xtn_profile_specific == 0xc0de) { xtn_hdr->profile_specific = htons(0xbede); diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 9b5a4bbb6..b1258c972 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -61,6 +61,8 @@ srtp_err_status_t srtp_validate(void); +srtp_err_status_t srtp_validate_cryptex(void); + #ifdef GCM srtp_err_status_t srtp_validate_gcm(void); #endif @@ -421,6 +423,19 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } + + /* + * run validation test against the reference packets - note + * that this test only covers the default policy + */ + printf("testing srtp_protect and srtp_unprotect against " + "reference cryptex packet\n"); + if (srtp_validate_cryptex() == srtp_err_status_ok) { + printf("passed\n\n"); + } else { + printf("failed\n"); + exit(1); + } #ifdef GCM printf("testing srtp_protect and srtp_unprotect against " @@ -1777,6 +1792,292 @@ srtp_err_status_t srtp_validate() return srtp_err_status_ok; } +/* + * srtp_validate_cryptex() verifies the correctness of libsrtp by comparing + * some computed packets against some pre-computed reference values. + * These packets were made with the default SRTP policy. + */ +struct test_vectors { + const char* name; + const char* plaintext; + const char* ciphertext; +}; + +srtp_err_status_t srtp_validate_cryptex() +{ + /* Plaintext packet with 1-byte header extension */ + const char* rtp_1bytehdrext_ref = + "900f1235" + "decafbad" + "cafebabe" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* AES-CTR/HMAC-SHA1 Ciphertext packet with 1-byte header extension */ + const char* srtp_1bytehdrext_cryptex = + "900f1235" + "decafbad" + "cafebabe" + "c0de0001" + "eb923652" + "51c3e036" + "f8de27e9" + "c27ee3e0" + "b4651d9f" + "bc4218a7" + "0244522f" + "34a5"; + + /* Plaintext packet with 2-byte header extension */ + const char* rtp_2bytehdrext_ref = + "900f1236" + "decafbad" + "cafebabe" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* AES-CTR/HMAC-SHA1 Ciphertext packet with 2-byte header extension */ + const char* srtp_2bytehdrext_cryptex = + "900f1236" + "decafbad" + "cafebabe" + "c2de0001" + "4ed9cc4e" + "6a712b30" + "96c5ca77" + "339d4204" + "ce0d7739" + "6cab6958" + "5fbce381" + "94a5"; + + /* Plaintext packet with 1-byte header extension and CSRC fields. */ + const char* srtp_1bytehdrext_cc_ref = + "920f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_1bytehdrext_cc_cryptex = + "920f1238" + "decafbad" + "cafebabe" + "8bb6e12b" + "5cff16dd" + "c0de0001" + "92838c8c" + "09e58393" + "e1de3a9a" + "74734d67" + "45671338" + "c3acf11d" + "a2df8423" + "bee0"; + + /* Plaintext packet with 2-byte header extension and CSRC fields. */ + const char* srtp_2bytehdrext_cc_ref = + "920f1239" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_2bytehdrext_cc_cryptex = + "920f1239" + "decafbad" + "cafebabe" + "f70e513e" + "b90b9b25" + "c2de0001" + "bbed4848" + "faa64466" + "5f3d7f34" + "125914e9" + "f4d0ae92" + "3c6f479b" + "95a0f7b5" + "3133"; + + /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ + const char* srtp_1byte_empty_hdrext_cc_ref = + "920f123a" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0000" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_1byte_empty_hdrext_cc_cryptex = + "920f123a" + "decafbad" + "cafebabe" + "7130b6ab" + "fe2ab0e3" + "c0de0000" + "e3d9f64b" + "25c9e74c" + "b4cf8e43" + "fb92e378" + "1c2c0cea" + "b6b3a499" + "a14c"; + + /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ + const char* srtp_2byte_empty_hdrext_cc_ref = + "920f123b" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000000" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_2byte_empty_hdrext_cc_cryptex = + "920f123b" + "decafbad" + "cafebabe" + "cbf24c12" + "4330e1c8" + "c2de0000" + "599dd45b" + "c9d687b6" + "03e8b59d" + "771fd38e" + "88b170e0" + "cd31e125" + "eabe"; + + struct test_vectors vectors[6] = { + {"Plaintext packet with 1-byte header extension", rtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex}, + {"Plaintext packet with 2-byte header extension", rtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex}, + {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex}, + {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex}, + {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex}, + {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex}, + }; + + srtp_t srtp_snd, srtp_recv; + srtp_err_status_t status; + int len, ref_len, enc_len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + memset(&policy, 0, sizeof(policy)); + srtp_crypto_policy_set_rtp_default(&policy.rtp); + srtp_crypto_policy_set_rtcp_default(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.use_cryptex = 1; + policy.next = NULL; + + status = srtp_create(&srtp_snd, &policy); + if (status) { + return status; + } + + for (int i=0; i<6; ++i) { + uint8_t packet[1400]; + uint8_t reference[1400]; + uint8_t ciphertext[1400]; + + /* Initialize reference test vectors */ + ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; + enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; + + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n",vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); + + status = srtp_protect(srtp_snd, packet, &len); + if (status || (len != enc_len)) { + return srtp_err_status_fail; + } + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); + + if (srtp_octet_string_is_eq(packet, ciphertext, len)) { + return srtp_err_status_fail; + } + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) { + return status; + } + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, packet, &len); + if (status || (len != ref_len)) { + return status; + } + + if (srtp_octet_string_is_eq(packet, reference, len)) { + return srtp_err_status_fail; + } + } + + status = srtp_dealloc(srtp_snd); + if (status) { + return status; + } + + status = srtp_dealloc(srtp_recv); + if (status) { + return status; + } + + return srtp_err_status_ok; +} + #ifdef GCM /* * srtp_validate_gcm() verifies the correctness of libsrtp by comparing diff --git a/test/util.c b/test/util.c index c0f761490..efba5f2cc 100644 --- a/test/util.c +++ b/test/util.c @@ -117,7 +117,7 @@ uint8_t nibble_to_hex_char(uint8_t nibble) * hex_string_to_octet_string converts a hexadecimal string * of length 2 * len to a raw octet string of length len */ -int hex_string_to_octet_string(char *raw, char *hex, int len) +int hex_string_to_octet_string(char *raw, const char *hex, int len) { uint8_t x; int tmp; From ce58dd67af9a46c51e359fe1adb1ae11b3a54b6a Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Mon, 16 Nov 2020 23:28:15 +0100 Subject: [PATCH 10/17] Fix AAD and add tests --- srtp/srtp.c | 106 ++++--- test/srtp_driver.c | 719 ++++++++++++++++++++++++++++++++------------- test/util.h | 2 +- 3 files changed, 577 insertions(+), 250 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 1262726ab..e1fa5688b 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1702,6 +1702,7 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, uint8_t *mki_location = NULL; int xtn_hdr_length = 0; int xtn_profile_specific = 0; + uint32_t xtn_hdr_profile_and_value = 0; debug_print0(mod_srtp, "function srtp_protect_aead"); @@ -1744,20 +1745,23 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, } /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { + /* Change profiles by cryptex values */ + if (xtn_profile_specific == 0xbede) { + xtn_hdr_profile_and_value = htonl(0xc0de << 16 | xtn_hdr_length); + } else if (xtn_profile_specific == 0x1000) { + xtn_hdr_profile_and_value = htonl(0xc2de << 16 | xtn_hdr_length); + } else { + return srtp_err_status_parse_err; + } + /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Move CSRCS so it is contiguos with extension header block */ + /* Move CSRCS so block is contiguous with extension header block */ for (unsigned char i = hdr->cc; i > 0 ; --i) - csrcs[i] = csrcs[i - 1]; + csrcs[i] = csrcs[i - 1]; + /* Move profile and length before the CSRCs */ + csrcs[0] = xtn_hdr_profile_and_value; + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; - /* Change profiles by cryptex values and set it before moved csrcs */ - if (xtn_profile_specific == 0xbede) { - csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); - } else if (xtn_profile_specific == 0x1000) { - csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); - } else { - printf("%x",xtn_profile_specific); - return srtp_err_status_parse_err; - } } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; if (hdr->x == 1) { @@ -1845,11 +1849,14 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, return srtp_err_status_cipher_fail; } - if (stream->use_cryptex && xtn_hdr) { - uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Restore CSRCs block before sending if using cryptex */ + if (stream->use_cryptex && xtn_hdr && hdr->cc) { /* Restore CSRCS to its original position */ + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; for (unsigned char i = 0; i < hdr->cc; ++i) csrcs[i] = csrcs[i + 1]; + /* Restore extension header profile and length */ + *(uint32_t *)xtn_hdr = xtn_hdr_profile_and_value; } /* @@ -1902,7 +1909,8 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, int xtn_hdr_length = 0; int xtn_profile_specific = 0; unsigned int use_cryptex = 0; - + uint32_t xtn_hdr_profile_and_value = 0; + debug_print0(mod_srtp, "function srtp_unprotect_aead"); #ifdef NO_64BIT_MATH @@ -1952,18 +1960,16 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { + /* Get the 4 bytes of defined by profile and length */ + xtn_hdr_profile_and_value = *(uint32_t *)&xtn_hdr->profile_specific; + /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Move CSRCS so it is contiguos with extension header block */ - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i + 1] = csrcs[i]; - /* Change profiles by cryptex values and set it before moved csrcs */ - if (xtn_profile_specific == 0xbede) { - csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); - } else if (xtn_profile_specific == 0x1000) { - csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); - } else { - return srtp_err_status_parse_err; - } + /* Move CSRCS so block is contiguous with extension header block */ + for (unsigned char i = hdr->cc; i > 0 ; --i) + csrcs[i] = csrcs[i - 1]; + /* Move defined by profile before the CSRCs block */ + csrcs[0] = xtn_hdr_profile_and_value; + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; use_cryptex = 1; } else { @@ -2145,6 +2151,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, int advance_packet_index = 0; int xtn_hdr_length = 0; int xtn_profile_specific = 0; + uint32_t xtn_hdr_profile_and_value = 0; debug_print0(mod_srtp, "function srtp_protect"); @@ -2266,18 +2273,22 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, } /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { - uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Move CSRCS so block is contiguous with extension header block */ - for (unsigned char i = hdr->cc; i > 0 ; --i) - csrcs[i] = csrcs[i - 1]; - /* Change profiles by cryptex values and set it before moved csrcs */ + /* Change profiles by cryptex values */ if (xtn_profile_specific == 0xbede) { - csrcs[0] = htonl(0xc0de << 16 | xtn_hdr_length); + xtn_hdr_profile_and_value = htonl(0xc0de << 16 | xtn_hdr_length); } else if (xtn_profile_specific == 0x1000) { - csrcs[0] = htonl(0xc2de << 16 | xtn_hdr_length); + xtn_hdr_profile_and_value = htonl(0xc2de << 16 | xtn_hdr_length); } else { return srtp_err_status_parse_err; } + /* Get CSRCs block position or profile if no CSRCs */ + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + /* Move CSRCS so block is contiguous with extension header block */ + for (unsigned char i = hdr->cc; i > 0 ; --i) + csrcs[i] = csrcs[i - 1]; + /* Move profile and length before the CSRCs */ + csrcs[0] = xtn_hdr_profile_and_value; + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; @@ -2430,13 +2441,15 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, (unsigned int *)&enc_octet_len); if (status) return srtp_err_status_cipher_fail; - - if (stream->use_cryptex && xtn_hdr) { - uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Restore CSRCS to its original position */ - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i] = csrcs[i + 1]; - } + /* Restore CSRCs block before sending if using cryptex */ + if (stream->use_cryptex && xtn_hdr && hdr->cc) { + /* Restore CSRCS to its original position */ + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i + 1]; + /* Restore extension header profile and length */ + *(uint32_t *)xtn_hdr = xtn_hdr_profile_and_value; + } } /* @@ -2464,7 +2477,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, if (status) return srtp_err_status_auth_fail; } - + if (auth_tag) { /* increase the packet length by the length of the auth tag */ *pkt_octet_len += tag_len; @@ -2511,6 +2524,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, int xtn_hdr_length = 0; int xtn_profile_specific = 0; unsigned int use_cryptex = 0; + uint32_t xtn_hdr_profile_and_value = 0; debug_print0(mod_srtp, "function srtp_unprotect"); @@ -2738,10 +2752,16 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { + /* Get the 4 bytes of defined by profile and length */ + xtn_hdr_profile_and_value = *(uint32_t *)&xtn_hdr->profile_specific; + /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - /* Move CSRCS so it is contiguos with extension header block */ - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i + 1] = csrcs[i]; + /* Move CSRCS so block is contiguous with extension header block */ + for (unsigned char i = hdr->cc; i > 0 ; --i) + csrcs[i] = csrcs[i - 1]; + /* Move defined by profile before the CSRCs block */ + csrcs[0] = xtn_hdr_profile_and_value; + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; use_cryptex = 1; } else { diff --git a/test/srtp_driver.c b/test/srtp_driver.c index b1258c972..8d00f8083 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -65,6 +65,8 @@ srtp_err_status_t srtp_validate_cryptex(void); #ifdef GCM srtp_err_status_t srtp_validate_gcm(void); + +srtp_err_status_t srtp_validate_gcm_cryptex(void); #endif srtp_err_status_t srtp_validate_encrypted_extensions_headers(void); @@ -124,6 +126,12 @@ double mips_estimate(int num_trials, int *ignore); #define TEST_MKI_ID_SIZE 4 +typedef struct test_vectors_t { + const char* name; + const char* plaintext; + const char* ciphertext; +} test_vectors_t; + extern uint8_t test_key[46]; extern uint8_t test_key_2[46]; extern uint8_t test_mki_id[TEST_MKI_ID_SIZE]; @@ -423,7 +431,7 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } - + /* * run validation test against the reference packets - note * that this test only covers the default policy @@ -446,6 +454,15 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } + + printf("testing srtp_protect and srtp_unprotect against " + "reference cryptex packet using GCM\n"); + if (srtp_validate_gcm_cryptex() == srtp_err_status_ok) { + printf("passed\n\n"); + } else { + printf("failed\n"); + exit(1); + } #endif printf("testing srtp_protect and srtp_unprotect against " @@ -1797,191 +1814,185 @@ srtp_err_status_t srtp_validate() * some computed packets against some pre-computed reference values. * These packets were made with the default SRTP policy. */ -struct test_vectors { - const char* name; - const char* plaintext; - const char* ciphertext; -}; - srtp_err_status_t srtp_validate_cryptex() { /* Plaintext packet with 1-byte header extension */ - const char* rtp_1bytehdrext_ref = - "900f1235" - "decafbad" - "cafebabe" - "bede0001" - "51000200" - "abababab" - "abababab" - "abababab" - "abababab"; + const char* srtp_1bytehdrext_ref = + "900f1235" + "decafbad" + "cafebabe" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; /* AES-CTR/HMAC-SHA1 Ciphertext packet with 1-byte header extension */ const char* srtp_1bytehdrext_cryptex = - "900f1235" - "decafbad" - "cafebabe" - "c0de0001" - "eb923652" - "51c3e036" - "f8de27e9" - "c27ee3e0" - "b4651d9f" - "bc4218a7" - "0244522f" - "34a5"; + "900f1235" + "decafbad" + "cafebabe" + "c0de0001" + "eb923652" + "51c3e036" + "f8de27e9" + "c27ee3e0" + "b4651d9f" + "bc4218a7" + "0244522f" + "34a5"; /* Plaintext packet with 2-byte header extension */ - const char* rtp_2bytehdrext_ref = - "900f1236" - "decafbad" - "cafebabe" - "10000001" - "05020002" - "abababab" - "abababab" - "abababab" - "abababab"; + const char* srtp_2bytehdrext_ref = + "900f1236" + "decafbad" + "cafebabe" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; /* AES-CTR/HMAC-SHA1 Ciphertext packet with 2-byte header extension */ const char* srtp_2bytehdrext_cryptex = - "900f1236" - "decafbad" - "cafebabe" - "c2de0001" - "4ed9cc4e" - "6a712b30" - "96c5ca77" - "339d4204" - "ce0d7739" - "6cab6958" - "5fbce381" - "94a5"; + "900f1236" + "decafbad" + "cafebabe" + "c2de0001" + "4ed9cc4e" + "6a712b30" + "96c5ca77" + "339d4204" + "ce0d7739" + "6cab6958" + "5fbce381" + "94a5"; /* Plaintext packet with 1-byte header extension and CSRC fields. */ const char* srtp_1bytehdrext_cc_ref = - "920f1238" - "decafbad" - "cafebabe" - "0001e240" - "0000b26e" - "bede0001" - "51000200" - "abababab" - "abababab" - "abababab" - "abababab"; + "920f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; const char* srtp_1bytehdrext_cc_cryptex = - "920f1238" - "decafbad" - "cafebabe" - "8bb6e12b" - "5cff16dd" - "c0de0001" - "92838c8c" - "09e58393" - "e1de3a9a" - "74734d67" - "45671338" - "c3acf11d" - "a2df8423" - "bee0"; + "920f1238" + "decafbad" + "cafebabe" + "8bb6e12b" + "5cff16dd" + "c0de0001" + "92838c8c" + "09e58393" + "e1de3a9a" + "74734d67" + "45671338" + "c3acf11d" + "a2df8423" + "bee0"; /* Plaintext packet with 2-byte header extension and CSRC fields. */ const char* srtp_2bytehdrext_cc_ref = - "920f1239" - "decafbad" - "cafebabe" - "0001e240" - "0000b26e" - "10000001" - "05020002" - "abababab" - "abababab" - "abababab" - "abababab"; + "920f1239" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; const char* srtp_2bytehdrext_cc_cryptex = - "920f1239" - "decafbad" - "cafebabe" - "f70e513e" - "b90b9b25" - "c2de0001" - "bbed4848" - "faa64466" - "5f3d7f34" - "125914e9" - "f4d0ae92" - "3c6f479b" - "95a0f7b5" - "3133"; + "920f1239" + "decafbad" + "cafebabe" + "f70e513e" + "b90b9b25" + "c2de0001" + "bbed4848" + "faa64466" + "5f3d7f34" + "125914e9" + "f4d0ae92" + "3c6f479b" + "95a0f7b5" + "3133"; /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ const char* srtp_1byte_empty_hdrext_cc_ref = - "920f123a" - "decafbad" - "cafebabe" - "0001e240" - "0000b26e" - "bede0000" - "abababab" - "abababab" - "abababab" - "abababab"; + "920f123a" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0000" + "abababab" + "abababab" + "abababab" + "abababab"; const char* srtp_1byte_empty_hdrext_cc_cryptex = - "920f123a" - "decafbad" - "cafebabe" - "7130b6ab" - "fe2ab0e3" - "c0de0000" - "e3d9f64b" - "25c9e74c" - "b4cf8e43" - "fb92e378" - "1c2c0cea" - "b6b3a499" - "a14c"; + "920f123a" + "decafbad" + "cafebabe" + "7130b6ab" + "fe2ab0e3" + "c0de0000" + "e3d9f64b" + "25c9e74c" + "b4cf8e43" + "fb92e378" + "1c2c0cea" + "b6b3a499" + "a14c"; /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ const char* srtp_2byte_empty_hdrext_cc_ref = - "920f123b" - "decafbad" - "cafebabe" - "0001e240" - "0000b26e" - "10000000" - "abababab" - "abababab" - "abababab" - "abababab"; + "920f123b" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000000" + "abababab" + "abababab" + "abababab" + "abababab"; const char* srtp_2byte_empty_hdrext_cc_cryptex = - "920f123b" - "decafbad" - "cafebabe" - "cbf24c12" - "4330e1c8" - "c2de0000" - "599dd45b" - "c9d687b6" - "03e8b59d" - "771fd38e" - "88b170e0" - "cd31e125" - "eabe"; + "920f123b" + "decafbad" + "cafebabe" + "cbf24c12" + "4330e1c8" + "c2de0000" + "599dd45b" + "c9d687b6" + "03e8b59d" + "771fd38e" + "88b170e0" + "cd31e125" + "eabe"; - struct test_vectors vectors[6] = { - {"Plaintext packet with 1-byte header extension", rtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex}, - {"Plaintext packet with 2-byte header extension", rtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex}, - {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex}, - {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex}, - {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex}, - {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex}, + struct test_vectors_t vectors[6] = { + {"Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex}, + {"Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex}, + {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex}, + {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex}, + {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex}, + {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex}, }; srtp_t srtp_snd, srtp_recv; @@ -2011,58 +2022,58 @@ srtp_err_status_t srtp_validate_cryptex() } for (int i=0; i<6; ++i) { - uint8_t packet[1400]; - uint8_t reference[1400]; - uint8_t ciphertext[1400]; - - /* Initialize reference test vectors */ - ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; - enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; - - /* Initialize test packet */ - len = ref_len; - memcpy(packet, reference, len); - printf("%s\n",vectors[i].name); - /* - * protect plaintext, then compare with ciphertext - */ - debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); - - status = srtp_protect(srtp_snd, packet, &len); - if (status || (len != enc_len)) { - return srtp_err_status_fail; - } - - debug_print(mod_driver, "ciphertext:\n %s", - octet_string_hex_string(packet, len)); - debug_print(mod_driver, "ciphertext reference:\n %s", - octet_string_hex_string(ciphertext, len)); - - if (srtp_octet_string_is_eq(packet, ciphertext, len)) { - return srtp_err_status_fail; - } - - /* - * create a receiver session context comparable to the one created - * above - we need to do this so that the replay checking doesn't - * complain - */ - status = srtp_create(&srtp_recv, &policy); - if (status) { - return status; - } - - /* - * unprotect ciphertext, then compare with plaintext - */ - status = srtp_unprotect(srtp_recv, packet, &len); - if (status || (len != ref_len)) { - return status; - } - - if (srtp_octet_string_is_eq(packet, reference, len)) { - return srtp_err_status_fail; - } + uint8_t packet[1400]; + uint8_t reference[1400]; + uint8_t ciphertext[1400]; + + /* Initialize reference test vectors */ + ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; + enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; + + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n",vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); + + status = srtp_protect(srtp_snd, packet, &len); + if (status || (len != enc_len)) { + return srtp_err_status_fail; + } + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); + + if (srtp_octet_string_is_eq(packet, ciphertext, len)) { + return srtp_err_status_fail; + } + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) { + return status; + } + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, packet, &len); + if (status || (len != ref_len)) { + return status; + } + + if (srtp_octet_string_is_eq(packet, reference, len)) { + return srtp_err_status_fail; + } } status = srtp_dealloc(srtp_snd); @@ -2246,6 +2257,302 @@ srtp_err_status_t srtp_validate_gcm() return srtp_err_status_ok; } + +/* + * srtp_validate_gcm() verifies the correctness of libsrtp by comparing + * an computed packet against the known ciphertext for the plaintext. + */ +srtp_err_status_t srtp_validate_gcm_cryptex() +{ + // clang-format off + unsigned char test_key_gcm[28] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab + }; + + /* Plaintext packet with 1-byte header extension */ + const char* srtp_1bytehdrext_ref = + "900f1235" + "decafbad" + "cafebabe" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* GCM Ciphertext packet with 1-byte header extension */ + const char* srtp_1bytehdrext_cryptex_gcm = + "900f1235" + "decafbad" + "cafebabe" + "c0de0001" + "39972dc9" + "572c4d99" + "e8fc355d" + "e743fb2e" + "94f9d8ff" + "54e72f41" + "93bbc5c7" + "4ffab0fa" + "9fa0fbeb"; + + /* Plaintext packet with 2-byte header extension */ + const char* srtp_2bytehdrext_ref = + "900f1236" + "decafbad" + "cafebabe" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + /* GCM Ciphertext packet with 2-byte header extension */ + const char* srtp_2bytehdrext_cryptex_gcm = + "900f1236" + "decafbad" + "cafebabe" + "c2de0001" + "bb75a4c5" + "45cd1f41" + "3bdb7daa" + "2b1e3263" + "de313667" + "c9632490" + "81b35a65" + "f5cb6c88" + "b394235f"; + + /* Plaintext packet with 1-byte header extension and CSRC fields. */ + const char* srtp_1bytehdrext_cc_ref = + "920f1238" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0001" + "51000200" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_1bytehdrext_cc_cryptex_gcm = + "920f1238decafbad" + "cafebabe" + "63bbccc4" + "a7f695c4" + "c0de0001" + "8ad7c71f" + "ac70a80c" + "92866b4c" + "6ba98546" + "ef913586" + "e95ffaaf" + "fe956885" + "bb0647a8" + "bc094ac8"; + + + /* Plaintext packet with 2-byte header extension and CSRC fields. */ + const char* srtp_2bytehdrext_cc_ref = + "920f1239" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000001" + "05020002" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_2bytehdrext_cc_cryptex_gcm = + "920f1239" + "decafbad" + "cafebabe" + "3680524f" + "8d312b00" + "c2de0001" + "c78d1200" + "38422bc1" + "11a7187a" + "18246f98" + "0c059cc6" + "bc9df8b6" + "26394eca" + "344e4b05" + "d80fea83"; + + /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ + const char* srtp_1byte_empty_hdrext_cc_ref = + "920f123a" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "bede0000" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_1byte_empty_hdrext_cc_cryptex_gcm = + "920f123a" + "decafbad" + "cafebabe" + "15b6bb43" + "37906fff" + "c0de0000" + "b7b96453" + "7a2b03ab" + "7ba5389c" + "e9331712" + "6b5d974d" + "f30c6884" + "dcb651c5" + "e120c1da"; + + /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ + const char* srtp_2byte_empty_hdrext_cc_ref = + "920f123b" + "decafbad" + "cafebabe" + "0001e240" + "0000b26e" + "10000000" + "abababab" + "abababab" + "abababab" + "abababab"; + + const char* srtp_2byte_empty_hdrext_cc_cryptex_gcm = + "920f123b" + "decafbad" + "cafebabe" + "dcb38c9e" + "48bf95f4" + "c2de0000" + "61ee432c" + "f9203170" + "76613258" + "d3ce4236" + "c06ac429" + "681ad084" + "13512dc9" + "8b5207d8"; + // clang-format on + + struct test_vectors_t vectors[6] = { + {"Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex_gcm}, + {"Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex_gcm}, + {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex_gcm}, + {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex_gcm}, + {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex_gcm}, + {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex_gcm}, + }; + + srtp_t srtp_snd, srtp_recv; + srtp_err_status_t status; + int len, ref_len, enc_len; + srtp_policy_t policy; + + /* + * create a session with a single stream using the default srtp + * policy and with the SSRC value 0xcafebabe + */ + memset(&policy, 0, sizeof(policy)); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtp); + srtp_crypto_policy_set_aes_gcm_128_16_auth(&policy.rtcp); + policy.ssrc.type = ssrc_specific; + policy.ssrc.value = 0xcafebabe; + policy.key = test_key_gcm; + policy.ekt = NULL; + policy.window_size = 128; + policy.allow_repeat_tx = 0; + policy.use_cryptex = 1; + policy.next = NULL; + + status = srtp_create(&srtp_snd, &policy); + if (status) { + return status; + } + + for (int i=0; i<6; ++i) { + uint8_t packet[1400]; + uint8_t reference[1400]; + uint8_t ciphertext[1400]; + + /* Initialize reference test vectors */ + ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; + enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; + + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n",vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); + + status = srtp_protect(srtp_snd, packet, &len); + if (status || (len != enc_len)) { + return srtp_err_status_fail; + } + + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); + + if (srtp_octet_string_is_eq(packet, ciphertext, len)) { + return srtp_err_status_fail; + } + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) { + return status; + } + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, packet, &len); + if (status || (len != ref_len)) { + return status; + } + + if (srtp_octet_string_is_eq(packet, reference, len)) { + return srtp_err_status_fail; + } + } + + status = srtp_dealloc(srtp_snd); + if (status) { + return status; + } + + status = srtp_dealloc(srtp_recv); + if (status) { + return status; + } + + return srtp_err_status_ok; +} + + #endif /* diff --git a/test/util.h b/test/util.h index d04b279b3..b1d56d9b2 100644 --- a/test/util.h +++ b/test/util.h @@ -46,7 +46,7 @@ #define MAX_PRINT_STRING_LEN 1024 -int hex_string_to_octet_string(char *raw, char *hex, int len); +int hex_string_to_octet_string(char *raw, const char *hex, int len); char *octet_string_hex_string(const void *s, int length); int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len); From 653637342504deaa4c2bc5e9601138ddad75692d Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Mon, 16 Nov 2020 23:33:42 +0100 Subject: [PATCH 11/17] format --- srtp/srtp.c | 52 ++++++++--------- test/srtp_driver.c | 135 ++++++++++++++++++++++++--------------------- 2 files changed, 100 insertions(+), 87 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index e1fa5688b..57320fa89 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1756,11 +1756,11 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ - for (unsigned char i = hdr->cc; i > 0 ; --i) + for (unsigned char i = hdr->cc; i > 0; --i) csrcs[i] = csrcs[i - 1]; /* Move profile and length before the CSRCs */ csrcs[0] = xtn_hdr_profile_and_value; - /* Start encrypting in the CSRCS block new position */ + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; @@ -1910,7 +1910,7 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, int xtn_profile_specific = 0; unsigned int use_cryptex = 0; uint32_t xtn_hdr_profile_and_value = 0; - + debug_print0(mod_srtp, "function srtp_unprotect_aead"); #ifdef NO_64BIT_MATH @@ -1965,11 +1965,11 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ - for (unsigned char i = hdr->cc; i > 0 ; --i) + for (unsigned char i = hdr->cc; i > 0; --i) csrcs[i] = csrcs[i - 1]; /* Move defined by profile before the CSRCs block */ csrcs[0] = xtn_hdr_profile_and_value; - /* Start encrypting in the CSRCS block new position */ + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; use_cryptex = 1; } else { @@ -2273,22 +2273,24 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, } /* If no header extension is present cryptex has no effect */ if (stream->use_cryptex && hdr->x) { - /* Change profiles by cryptex values */ + /* Change profiles by cryptex values */ if (xtn_profile_specific == 0xbede) { - xtn_hdr_profile_and_value = htonl(0xc0de << 16 | xtn_hdr_length); + xtn_hdr_profile_and_value = + htonl(0xc0de << 16 | xtn_hdr_length); } else if (xtn_profile_specific == 0x1000) { - xtn_hdr_profile_and_value = htonl(0xc2de << 16 | xtn_hdr_length); + xtn_hdr_profile_and_value = + htonl(0xc2de << 16 | xtn_hdr_length); } else { return srtp_err_status_parse_err; } - /* Get CSRCs block position or profile if no CSRCs */ + /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ - for (unsigned char i = hdr->cc; i > 0 ; --i) + for (unsigned char i = hdr->cc; i > 0; --i) csrcs[i] = csrcs[i - 1]; - /* Move profile and length before the CSRCs */ - csrcs[0] = xtn_hdr_profile_and_value; - /* Start encrypting in the CSRCS block new position */ + /* Move profile and length before the CSRCs */ + csrcs[0] = xtn_hdr_profile_and_value; + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; @@ -2441,15 +2443,15 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, (unsigned int *)&enc_octet_len); if (status) return srtp_err_status_cipher_fail; - /* Restore CSRCs block before sending if using cryptex */ - if (stream->use_cryptex && xtn_hdr && hdr->cc) { - /* Restore CSRCS to its original position */ - uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; - for (unsigned char i = 0; i < hdr->cc; ++i) - csrcs[i] = csrcs[i + 1]; - /* Restore extension header profile and length */ - *(uint32_t *)xtn_hdr = xtn_hdr_profile_and_value; - } + /* Restore CSRCs block before sending if using cryptex */ + if (stream->use_cryptex && xtn_hdr && hdr->cc) { + /* Restore CSRCS to its original position */ + uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; + for (unsigned char i = 0; i < hdr->cc; ++i) + csrcs[i] = csrcs[i + 1]; + /* Restore extension header profile and length */ + *(uint32_t *)xtn_hdr = xtn_hdr_profile_and_value; + } } /* @@ -2477,7 +2479,7 @@ srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, if (status) return srtp_err_status_auth_fail; } - + if (auth_tag) { /* increase the packet length by the length of the auth tag */ *pkt_octet_len += tag_len; @@ -2757,11 +2759,11 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ - for (unsigned char i = hdr->cc; i > 0 ; --i) + for (unsigned char i = hdr->cc; i > 0; --i) csrcs[i] = csrcs[i - 1]; /* Move defined by profile before the CSRCs block */ csrcs[0] = xtn_hdr_profile_and_value; - /* Start encrypting in the CSRCS block new position */ + /* Start encrypting in the CSRCS block new position */ enc_start = csrcs + 1; use_cryptex = 1; } else { diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 8d00f8083..4c0eded0f 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -127,9 +127,9 @@ double mips_estimate(int num_trials, int *ignore); #define TEST_MKI_ID_SIZE 4 typedef struct test_vectors_t { - const char* name; - const char* plaintext; - const char* ciphertext; + const char *name; + const char *plaintext; + const char *ciphertext; } test_vectors_t; extern uint8_t test_key[46]; @@ -431,8 +431,8 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } - - /* + + /* * run validation test against the reference packets - note * that this test only covers the default policy */ @@ -454,7 +454,7 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } - + printf("testing srtp_protect and srtp_unprotect against " "reference cryptex packet using GCM\n"); if (srtp_validate_gcm_cryptex() == srtp_err_status_ok) { @@ -2021,59 +2021,65 @@ srtp_err_status_t srtp_validate_cryptex() return status; } - for (int i=0; i<6; ++i) { - uint8_t packet[1400]; - uint8_t reference[1400]; - uint8_t ciphertext[1400]; - - /* Initialize reference test vectors */ - ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; - enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; - - /* Initialize test packet */ - len = ref_len; - memcpy(packet, reference, len); - printf("%s\n",vectors[i].name); - /* - * protect plaintext, then compare with ciphertext - */ - debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); - - status = srtp_protect(srtp_snd, packet, &len); - if (status || (len != enc_len)) { - return srtp_err_status_fail; - } + for (int i = 0; i < 6; ++i) { + uint8_t packet[1400]; + uint8_t reference[1400]; + uint8_t ciphertext[1400]; - debug_print(mod_driver, "ciphertext:\n %s", - octet_string_hex_string(packet, len)); - debug_print(mod_driver, "ciphertext reference:\n %s", - octet_string_hex_string(ciphertext, len)); + /* Initialize reference test vectors */ + ref_len = + hex_string_to_octet_string((char *)reference, vectors[i].plaintext, + sizeof(reference)) / + 2; + enc_len = hex_string_to_octet_string((char *)ciphertext, + vectors[i].ciphertext, + sizeof(ciphertext)) / + 2; - if (srtp_octet_string_is_eq(packet, ciphertext, len)) { - return srtp_err_status_fail; - } + /* Initialize test packet */ + len = ref_len; + memcpy(packet, reference, len); + printf("%s\n", vectors[i].name); + /* + * protect plaintext, then compare with ciphertext + */ + debug_print(mod_driver, "test vector: %s\n", vectors[i].name); - /* - * create a receiver session context comparable to the one created - * above - we need to do this so that the replay checking doesn't - * complain - */ - status = srtp_create(&srtp_recv, &policy); - if (status) { - return status; - } + status = srtp_protect(srtp_snd, packet, &len); + if (status || (len != enc_len)) { + return srtp_err_status_fail; + } - /* - * unprotect ciphertext, then compare with plaintext - */ - status = srtp_unprotect(srtp_recv, packet, &len); - if (status || (len != ref_len)) { - return status; - } + debug_print(mod_driver, "ciphertext:\n %s", + octet_string_hex_string(packet, len)); + debug_print(mod_driver, "ciphertext reference:\n %s", + octet_string_hex_string(ciphertext, len)); - if (srtp_octet_string_is_eq(packet, reference, len)) { - return srtp_err_status_fail; - } + if (srtp_octet_string_is_eq(packet, ciphertext, len)) { + return srtp_err_status_fail; + } + + /* + * create a receiver session context comparable to the one created + * above - we need to do this so that the replay checking doesn't + * complain + */ + status = srtp_create(&srtp_recv, &policy); + if (status) { + return status; + } + + /* + * unprotect ciphertext, then compare with plaintext + */ + status = srtp_unprotect(srtp_recv, packet, &len); + if (status || (len != ref_len)) { + return status; + } + + if (srtp_octet_string_is_eq(packet, reference, len)) { + return srtp_err_status_fail; + } } status = srtp_dealloc(srtp_snd); @@ -2484,23 +2490,29 @@ srtp_err_status_t srtp_validate_gcm_cryptex() return status; } - for (int i=0; i<6; ++i) { + for (int i = 0; i < 6; ++i) { uint8_t packet[1400]; uint8_t reference[1400]; uint8_t ciphertext[1400]; /* Initialize reference test vectors */ - ref_len = hex_string_to_octet_string((char*)reference, vectors[i].plaintext, sizeof(reference)) / 2; - enc_len = hex_string_to_octet_string((char*)ciphertext, vectors[i].ciphertext, sizeof(ciphertext)) / 2; + ref_len = + hex_string_to_octet_string((char *)reference, vectors[i].plaintext, + sizeof(reference)) / + 2; + enc_len = hex_string_to_octet_string((char *)ciphertext, + vectors[i].ciphertext, + sizeof(ciphertext)) / + 2; /* Initialize test packet */ len = ref_len; memcpy(packet, reference, len); - printf("%s\n",vectors[i].name); + printf("%s\n", vectors[i].name); /* * protect plaintext, then compare with ciphertext */ - debug_print(mod_driver, "test vector: %s\n", vectors[i].name ); + debug_print(mod_driver, "test vector: %s\n", vectors[i].name); status = srtp_protect(srtp_snd, packet, &len); if (status || (len != enc_len)) { @@ -2508,9 +2520,9 @@ srtp_err_status_t srtp_validate_gcm_cryptex() } debug_print(mod_driver, "ciphertext:\n %s", - octet_string_hex_string(packet, len)); + octet_string_hex_string(packet, len)); debug_print(mod_driver, "ciphertext reference:\n %s", - octet_string_hex_string(ciphertext, len)); + octet_string_hex_string(ciphertext, len)); if (srtp_octet_string_is_eq(packet, ciphertext, len)) { return srtp_err_status_fail; @@ -2552,7 +2564,6 @@ srtp_err_status_t srtp_validate_gcm_cryptex() return srtp_err_status_ok; } - #endif /* From fbf23e29d30df59b1ce62809f0c1c3f4b2b99395 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Mon, 16 Nov 2020 23:41:06 +0100 Subject: [PATCH 12/17] clang --- test/srtp_driver.c | 93 +++++++++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 38 deletions(-) diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 4c0eded0f..b43c21f45 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -1816,8 +1816,9 @@ srtp_err_status_t srtp_validate() */ srtp_err_status_t srtp_validate_cryptex() { + // clang-format off /* Plaintext packet with 1-byte header extension */ - const char* srtp_1bytehdrext_ref = + const char *srtp_1bytehdrext_ref = "900f1235" "decafbad" "cafebabe" @@ -1829,7 +1830,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab"; /* AES-CTR/HMAC-SHA1 Ciphertext packet with 1-byte header extension */ - const char* srtp_1bytehdrext_cryptex = + const char *srtp_1bytehdrext_cryptex = "900f1235" "decafbad" "cafebabe" @@ -1844,7 +1845,7 @@ srtp_err_status_t srtp_validate_cryptex() "34a5"; /* Plaintext packet with 2-byte header extension */ - const char* srtp_2bytehdrext_ref = + const char *srtp_2bytehdrext_ref = "900f1236" "decafbad" "cafebabe" @@ -1856,7 +1857,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab"; /* AES-CTR/HMAC-SHA1 Ciphertext packet with 2-byte header extension */ - const char* srtp_2bytehdrext_cryptex = + const char *srtp_2bytehdrext_cryptex = "900f1236" "decafbad" "cafebabe" @@ -1871,7 +1872,7 @@ srtp_err_status_t srtp_validate_cryptex() "94a5"; /* Plaintext packet with 1-byte header extension and CSRC fields. */ - const char* srtp_1bytehdrext_cc_ref = + const char *srtp_1bytehdrext_cc_ref = "920f1238" "decafbad" "cafebabe" @@ -1884,7 +1885,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab" "abababab"; - const char* srtp_1bytehdrext_cc_cryptex = + const char *srtp_1bytehdrext_cc_cryptex = "920f1238" "decafbad" "cafebabe" @@ -1901,7 +1902,7 @@ srtp_err_status_t srtp_validate_cryptex() "bee0"; /* Plaintext packet with 2-byte header extension and CSRC fields. */ - const char* srtp_2bytehdrext_cc_ref = + const char *srtp_2bytehdrext_cc_ref = "920f1239" "decafbad" "cafebabe" @@ -1914,7 +1915,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab" "abababab"; - const char* srtp_2bytehdrext_cc_cryptex = + const char *srtp_2bytehdrext_cc_cryptex = "920f1239" "decafbad" "cafebabe" @@ -1931,7 +1932,7 @@ srtp_err_status_t srtp_validate_cryptex() "3133"; /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ - const char* srtp_1byte_empty_hdrext_cc_ref = + const char *srtp_1byte_empty_hdrext_cc_ref = "920f123a" "decafbad" "cafebabe" @@ -1943,7 +1944,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab" "abababab"; - const char* srtp_1byte_empty_hdrext_cc_cryptex = + const char *srtp_1byte_empty_hdrext_cc_cryptex = "920f123a" "decafbad" "cafebabe" @@ -1959,7 +1960,7 @@ srtp_err_status_t srtp_validate_cryptex() "a14c"; /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ - const char* srtp_2byte_empty_hdrext_cc_ref = + const char *srtp_2byte_empty_hdrext_cc_ref = "920f123b" "decafbad" "cafebabe" @@ -1971,7 +1972,7 @@ srtp_err_status_t srtp_validate_cryptex() "abababab" "abababab"; - const char* srtp_2byte_empty_hdrext_cc_cryptex = + const char *srtp_2byte_empty_hdrext_cc_cryptex = "920f123b" "decafbad" "cafebabe" @@ -1985,14 +1986,22 @@ srtp_err_status_t srtp_validate_cryptex() "88b170e0" "cd31e125" "eabe"; - + + // clang-format on + struct test_vectors_t vectors[6] = { - {"Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex}, - {"Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex}, - {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex}, - {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex}, - {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex}, - {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex}, + { "Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, + srtp_1bytehdrext_cryptex }, + { "Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, + srtp_2bytehdrext_cryptex }, + { "Plaintext packet with 1-byte header extension and CSRC fields", + srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex }, + { "Plaintext packet with 2-byte header extension and CSRC fields", + srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex }, + { "Plaintext packet with empty 1-byte header extension and CSRC fields", + srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex }, + { "Plaintext packet with empty 2-byte header extension and CSRC fields", + srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex }, }; srtp_t srtp_snd, srtp_recv; @@ -2279,7 +2288,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() }; /* Plaintext packet with 1-byte header extension */ - const char* srtp_1bytehdrext_ref = + const char *srtp_1bytehdrext_ref = "900f1235" "decafbad" "cafebabe" @@ -2291,7 +2300,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab"; /* GCM Ciphertext packet with 1-byte header extension */ - const char* srtp_1bytehdrext_cryptex_gcm = + const char *srtp_1bytehdrext_cryptex_gcm = "900f1235" "decafbad" "cafebabe" @@ -2307,7 +2316,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "9fa0fbeb"; /* Plaintext packet with 2-byte header extension */ - const char* srtp_2bytehdrext_ref = + const char *srtp_2bytehdrext_ref = "900f1236" "decafbad" "cafebabe" @@ -2319,7 +2328,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab"; /* GCM Ciphertext packet with 2-byte header extension */ - const char* srtp_2bytehdrext_cryptex_gcm = + const char *srtp_2bytehdrext_cryptex_gcm = "900f1236" "decafbad" "cafebabe" @@ -2335,7 +2344,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "b394235f"; /* Plaintext packet with 1-byte header extension and CSRC fields. */ - const char* srtp_1bytehdrext_cc_ref = + const char *srtp_1bytehdrext_cc_ref = "920f1238" "decafbad" "cafebabe" @@ -2348,7 +2357,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab" "abababab"; - const char* srtp_1bytehdrext_cc_cryptex_gcm = + const char *srtp_1bytehdrext_cc_cryptex_gcm = "920f1238decafbad" "cafebabe" "63bbccc4" @@ -2366,7 +2375,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() /* Plaintext packet with 2-byte header extension and CSRC fields. */ - const char* srtp_2bytehdrext_cc_ref = + const char *srtp_2bytehdrext_cc_ref = "920f1239" "decafbad" "cafebabe" @@ -2379,7 +2388,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab" "abababab"; - const char* srtp_2bytehdrext_cc_cryptex_gcm = + const char *srtp_2bytehdrext_cc_cryptex_gcm = "920f1239" "decafbad" "cafebabe" @@ -2397,7 +2406,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "d80fea83"; /* Plaintext packet with empty 1-byte header extension and CSRC fields. */ - const char* srtp_1byte_empty_hdrext_cc_ref = + const char *srtp_1byte_empty_hdrext_cc_ref = "920f123a" "decafbad" "cafebabe" @@ -2409,7 +2418,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab" "abababab"; - const char* srtp_1byte_empty_hdrext_cc_cryptex_gcm = + const char *srtp_1byte_empty_hdrext_cc_cryptex_gcm = "920f123a" "decafbad" "cafebabe" @@ -2426,7 +2435,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "e120c1da"; /* Plaintext packet with empty 2-byte header extension and CSRC fields. */ - const char* srtp_2byte_empty_hdrext_cc_ref = + const char *srtp_2byte_empty_hdrext_cc_ref = "920f123b" "decafbad" "cafebabe" @@ -2438,7 +2447,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab" "abababab"; - const char* srtp_2byte_empty_hdrext_cc_cryptex_gcm = + const char *srtp_2byte_empty_hdrext_cc_cryptex_gcm = "920f123b" "decafbad" "cafebabe" @@ -2454,14 +2463,22 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "13512dc9" "8b5207d8"; // clang-format on - + struct test_vectors_t vectors[6] = { - {"Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, srtp_1bytehdrext_cryptex_gcm}, - {"Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, srtp_2bytehdrext_cryptex_gcm}, - {"Plaintext packet with 1-byte header extension and CSRC fields", srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex_gcm}, - {"Plaintext packet with 2-byte header extension and CSRC fields", srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex_gcm}, - {"Plaintext packet with empty 1-byte header extension and CSRC fields", srtp_1byte_empty_hdrext_cc_ref, srtp_1byte_empty_hdrext_cc_cryptex_gcm}, - {"Plaintext packet with empty 2-byte header extension and CSRC fields", srtp_2byte_empty_hdrext_cc_ref, srtp_2byte_empty_hdrext_cc_cryptex_gcm}, + { "Plaintext packet with 1-byte header extension", srtp_1bytehdrext_ref, + srtp_1bytehdrext_cryptex_gcm }, + { "Plaintext packet with 2-byte header extension", srtp_2bytehdrext_ref, + srtp_2bytehdrext_cryptex_gcm }, + { "Plaintext packet with 1-byte header extension and CSRC fields", + srtp_1bytehdrext_cc_ref, srtp_1bytehdrext_cc_cryptex_gcm }, + { "Plaintext packet with 2-byte header extension and CSRC fields", + srtp_2bytehdrext_cc_ref, srtp_2bytehdrext_cc_cryptex_gcm }, + { "Plaintext packet with empty 1-byte header extension and CSRC fields", + srtp_1byte_empty_hdrext_cc_ref, + srtp_1byte_empty_hdrext_cc_cryptex_gcm }, + { "Plaintext packet with empty 2-byte header extension and CSRC fields", + srtp_2byte_empty_hdrext_cc_ref, + srtp_2byte_empty_hdrext_cc_cryptex_gcm }, }; srtp_t srtp_snd, srtp_recv; From 3f21c3ee7101f1f67d0a191fabed5865dc909b04 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Tue, 24 Aug 2021 16:38:50 +0200 Subject: [PATCH 13/17] fix warnings --- srtp/srtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 665948445..479435b4e 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1957,7 +1957,7 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { /* Get the 4 bytes of defined by profile and length */ - xtn_hdr_profile_and_value = *(uint32_t *)&xtn_hdr->profile_specific; + xtn_hdr_profile_and_value = *(uint32_t*)xtn_hdr; /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ @@ -2751,7 +2751,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { /* Get the 4 bytes of defined by profile and length */ - xtn_hdr_profile_and_value = *(uint32_t *)&xtn_hdr->profile_specific; + xtn_hdr_profile_and_value = *(uint32_t*)xtn_hdr; /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ From 5124a97b6bd2f52c61c1717242c4e1e47e8e07ff Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Tue, 24 Aug 2021 16:39:35 +0200 Subject: [PATCH 14/17] rename policy.ekt to policy.deprecated_ekt to aling with master --- test/srtp_driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/srtp_driver.c b/test/srtp_driver.c index be849b407..79efc13b3 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -2037,7 +2037,7 @@ srtp_err_status_t srtp_validate_cryptex() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.use_cryptex = 1; @@ -2514,7 +2514,7 @@ srtp_err_status_t srtp_validate_gcm_cryptex() policy.ssrc.type = ssrc_specific; policy.ssrc.value = 0xcafebabe; policy.key = test_key_gcm; - policy.ekt = NULL; + policy.deprecated_ekt = NULL; policy.window_size = 128; policy.allow_repeat_tx = 0; policy.use_cryptex = 1; From f8a374b83846b9062562e1b206c21ea81dc4cdb7 Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Sun, 29 Aug 2021 12:56:19 +0200 Subject: [PATCH 15/17] fix format --- srtp/srtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 479435b4e..6f4ac78bb 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -1957,7 +1957,7 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { /* Get the 4 bytes of defined by profile and length */ - xtn_hdr_profile_and_value = *(uint32_t*)xtn_hdr; + xtn_hdr_profile_and_value = *(uint32_t *)xtn_hdr; /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ @@ -2751,7 +2751,7 @@ srtp_err_status_t srtp_unprotect_mki(srtp_ctx_t *ctx, /* Check if the profile is the one for cryptex */ if (xtn_profile_specific == 0xc0de || xtn_profile_specific == 0xc2de) { /* Get the 4 bytes of defined by profile and length */ - xtn_hdr_profile_and_value = *(uint32_t*)xtn_hdr; + xtn_hdr_profile_and_value = *(uint32_t *)xtn_hdr; /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ From 90d2345b7b74a2a07be4b2401c122af84efca14b Mon Sep 17 00:00:00 2001 From: Sergio Garcia Murillo Date: Sun, 29 Aug 2021 12:56:59 +0200 Subject: [PATCH 16/17] fix mem leak on deallocating recv sessions --- test/srtp_driver.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 79efc13b3..7e0dfe26b 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -2107,14 +2107,14 @@ srtp_err_status_t srtp_validate_cryptex() if (srtp_octet_string_is_eq(packet, reference, len)) { return srtp_err_status_fail; } - } - status = srtp_dealloc(srtp_snd); - if (status) { - return status; + status = srtp_dealloc(srtp_recv); + if (status) { + return status; + } } - status = srtp_dealloc(srtp_recv); + status = srtp_dealloc(srtp_snd); if (status) { return status; } @@ -2584,14 +2584,14 @@ srtp_err_status_t srtp_validate_gcm_cryptex() if (srtp_octet_string_is_eq(packet, reference, len)) { return srtp_err_status_fail; } - } - status = srtp_dealloc(srtp_snd); - if (status) { - return status; + status = srtp_dealloc(srtp_recv); + if (status) { + return status; + } } - status = srtp_dealloc(srtp_recv); + status = srtp_dealloc(srtp_snd); if (status) { return status; } From 36734d92eabdccead057b4a2417e4d9e319e914c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20B=C3=BChler?= Date: Sun, 8 Sep 2024 18:22:35 +0200 Subject: [PATCH 17/17] port some of cryptex support on to main Due to support for non in-place io the existing code that always modifies the input buffer maybe not always be appropriate, this looks at alternatives. Encrypted csrc's when using gcm is currently not support and disabled. --- srtp/srtp.c | 151 ++++++++++++++++++++++++++++++++++++++++----- test/srtp_driver.c | 101 +++++++++--------------------- 2 files changed, 165 insertions(+), 87 deletions(-) diff --git a/srtp/srtp.c b/srtp/srtp.c index 76b1504f2..b568066e8 100644 --- a/srtp/srtp.c +++ b/srtp/srtp.c @@ -121,6 +121,42 @@ static size_t srtp_get_rtp_xtn_hdr_len(const srtp_hdr_t *hdr, return (ntohs(xtn_hdr->length) + 1u) * 4u; } +static uint16_t srtp_get_rtp_xtn_hdr_profile(const srtp_hdr_t *hdr, + const uint8_t *rtp) +{ + const srtp_hdr_xtnd_t *xtn_hdr = + (const srtp_hdr_xtnd_t *)(rtp + srtp_get_rtp_hdr_len(hdr)); + return ntohs(xtn_hdr->profile_specific); +} + +static bool srtp_is_cryptex_encrypted(const srtp_hdr_t *hdr, const uint8_t *rtp) +{ + uint16_t profile = srtp_get_rtp_xtn_hdr_profile(hdr, rtp); + return profile == 0xc0de || profile == 0xc2de; +} + +static void srtp_set_cryptex_profile(const srtp_hdr_t *hdr, uint8_t *rtp) +{ + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr, rtp); + uint16_t profile = ntohs(xtn_hdr->profile_specific); + if (profile == 0xbede) { + xtn_hdr->profile_specific = htons(0xc0de); + } else if (profile == 0x1000) { + xtn_hdr->profile_specific = htons(0xc2de); + } +} + +static void srtp_clear_cryptex_profile(const srtp_hdr_t *hdr, uint8_t *rtp) +{ + srtp_hdr_xtnd_t *xtn_hdr = srtp_get_rtp_xtn_hdr(hdr, rtp); + uint16_t profile = ntohs(xtn_hdr->profile_specific); + if (profile == 0xc0de) { + xtn_hdr->profile_specific = htons(0xbede); + } else if (profile == 0xc2de) { + xtn_hdr->profile_specific = htons(0x1000); + } +} + static srtp_err_status_t srtp_validate_rtp_header(const uint8_t *rtp, size_t pkt_octet_len) { @@ -1898,8 +1934,21 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, enc_start = srtp_get_rtp_hdr_len(hdr); if (hdr->x == 1) { enc_start += srtp_get_rtp_xtn_hdr_len(hdr, rtp); -#if 0 + } + + if (stream->use_cryptex && stream->rtp_services & sec_serv_conf) { + if (hdr->cc && hdr->x == 0) { + /* Cryptex can only encrypt CSRCS if header extension is present */ + /* Not 100% correct, it could have inserted empty header ext */ + return srtp_err_status_parse_err; + } + if (hdr->x == 1) { + enc_start -= + (srtp_get_rtp_xtn_hdr_len(hdr, rtp) - octets_in_rtp_xtn_hdr); + } + } +#if 0 /* Cryptex can only encrypt CSRCS if header extension is present*/ if (stream->use_cryptex && hdr->cc && !hdr->x) { return srtp_err_status_parse_err; @@ -1934,8 +1983,8 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, if (hdr->x == 1) { enc_start += (xtn_hdr_length + 1); } -#endif } +#endif /* note: the passed size is without the auth tag */ if (enc_start > rtp_len) { @@ -2011,6 +2060,11 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, } } + if (stream->use_cryptex && stream->rtp_services & sec_serv_conf && + hdr->x == 1) { + srtp_set_cryptex_profile(hdr, srtp); + } + /* * Set the AAD over the RTP header */ @@ -2032,6 +2086,8 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, if (stream->use_mki) { srtp_inject_mki(srtp + enc_start + enc_octet_len, session_keys, stream->mki_size); + } + #if 0 /* Restore CSRCs block before sending if using cryptex */ if (stream->use_cryptex && xtn_hdr && hdr->cc) { @@ -2053,7 +2109,6 @@ static srtp_err_status_t srtp_protect_aead(srtp_ctx_t *ctx, if (status) { return (srtp_err_status_cipher_fail); #endif - } *srtp_len = enc_start + enc_octet_len; @@ -2123,6 +2178,15 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, enc_start = srtp_get_rtp_hdr_len(hdr); if (hdr->x == 1) { enc_start += srtp_get_rtp_xtn_hdr_len(hdr, srtp); + } + + if (stream->use_cryptex && hdr->x == 1) { + if (srtp_is_cryptex_encrypted(hdr, srtp)) { + enc_start -= + (srtp_get_rtp_xtn_hdr_len(hdr, srtp) - octets_in_rtp_xtn_hdr); + } + } + #if 0 /* * find starting point for decryption and length of data to be @@ -2156,8 +2220,8 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, if (hdr->x == 1) { enc_start += (xtn_hdr_length + 1); } -#endif } +#endif if (enc_start > srtp_len - tag_len - stream->mki_size) { return srtp_err_status_parse_err; @@ -2223,7 +2287,10 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, return status; } - if (hdr->x == 1 && session_keys->rtp_xtn_hdr_cipher) { + if (stream->use_cryptex && hdr->x == 1) { + srtp_clear_cryptex_profile(hdr, rtp); + } + #if 0 if (use_cryptex) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; @@ -2240,9 +2307,9 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx, return srtp_err_status_parse_err; } } - - if (xtn_hdr && session_keys->rtp_xtn_hdr_cipher) { #endif + + if (hdr->x == 1 && session_keys->rtp_xtn_hdr_cipher) { /* * extensions header encryption RFC 6904 */ @@ -2457,6 +2524,20 @@ srtp_err_status_t srtp_protect(srtp_t ctx, enc_start = srtp_get_rtp_hdr_len(hdr); if (hdr->x == 1) { enc_start += srtp_get_rtp_xtn_hdr_len(hdr, rtp); + } + + if (stream->use_cryptex && stream->rtp_services & sec_serv_conf) { + if (hdr->cc && hdr->x == 0) { + /* Cryptex can only encrypt CSRCS if header extension is present */ + /* Not 100% correct, it could have inserted empty header ext */ + return srtp_err_status_parse_err; + } + if (hdr->x == 1) { + enc_start -= + (srtp_get_rtp_xtn_hdr_len(hdr, rtp) - octets_in_rtp_xtn_hdr); + } + } + #if 0 if (stream->rtp_services & sec_serv_conf) { /* Cryptex can only encrypt CSRCS if header extension is present*/ @@ -2479,8 +2560,8 @@ srtp_err_status_t srtp_protect(srtp_t ctx, xtn_hdr_profile_and_value = htonl(0xc2de << 16 | xtn_hdr_length); } else { - return srtp_err_status_parse_err; - } + return srtp_err_status_parse_err; + } /* Get CSRCs block position or profile if no CSRCs */ uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Move CSRCS so block is contiguous with extension header block */ @@ -2492,7 +2573,7 @@ srtp_err_status_t srtp_protect(srtp_t ctx, enc_start = csrcs + 1; } else { enc_start = (uint32_t *)hdr + uint32s_in_rtp_header + hdr->cc; - if (hdr->x == 1) { + if (hdr->x == 1) { enc_start += (xtn_hdr_length + 1); } } @@ -2505,8 +2586,8 @@ srtp_err_status_t srtp_protect(srtp_t ctx, return srtp_err_status_parse_err; } else { enc_start = NULL; -#endif } +#endif if (enc_start > rtp_len) { return srtp_err_status_parse_err; @@ -2634,6 +2715,17 @@ srtp_err_status_t srtp_protect(srtp_t ctx, /* if we're encrypting, exor keystream into the message */ if (stream->rtp_services & sec_serv_conf) { + /* CSRCs are in dst header already, enc in place */ + if (stream->use_cryptex && hdr->cc) { + uint8_t *cc_list = srtp + octets_in_rtp_header; + size_t cc_list_size = hdr->cc * 4; + status = srtp_cipher_encrypt(session_keys->rtp_cipher, cc_list, + cc_list_size, cc_list, &cc_list_size); + if (status) { + return srtp_err_status_cipher_fail; + } + } + status = srtp_cipher_encrypt(session_keys->rtp_cipher, rtp + enc_start, enc_octet_len, srtp + enc_start, &enc_octet_len); @@ -2643,6 +2735,13 @@ srtp_err_status_t srtp_protect(srtp_t ctx, } else if (rtp != srtp) { /* if no encryption and not-inplace then need to copy rest of packet */ memcpy(srtp + enc_start, rtp + enc_start, enc_octet_len); + } + + if (stream->use_cryptex && stream->rtp_services & sec_serv_conf && + hdr->x == 1) { + srtp_set_cryptex_profile(hdr, srtp); + } + #if 0 /* Restore CSRCs block before sending if using cryptex */ if (stream->use_cryptex && xtn_hdr && hdr->cc) { @@ -2653,8 +2752,8 @@ srtp_err_status_t srtp_protect(srtp_t ctx, /* Restore extension header profile and length */ *(uint32_t *)xtn_hdr = xtn_hdr_profile_and_value; } -#endif } +#endif /* * if we're authenticating, run authentication function and put result @@ -2848,6 +2947,13 @@ srtp_err_status_t srtp_unprotect(srtp_t ctx, enc_start += srtp_get_rtp_xtn_hdr_len(hdr, srtp); } + if (stream->use_cryptex && hdr->x == 1) { + if (srtp_is_cryptex_encrypted(hdr, srtp)) { + enc_start -= + (srtp_get_rtp_xtn_hdr_len(hdr, srtp) - octets_in_rtp_xtn_hdr); + } + } + if (enc_start > srtp_len - tag_len - stream->mki_size) { return srtp_err_status_parse_err; } @@ -2975,6 +3081,7 @@ srtp_err_status_t srtp_unprotect(srtp_t ctx, enc_start = NULL; } #endif + /* * update the key usage limit, and check it to make sure that we * didn't just hit either the soft limit or the hard limit, and call @@ -3004,6 +3111,17 @@ srtp_err_status_t srtp_unprotect(srtp_t ctx, /* if we're decrypting, add keystream into ciphertext */ if (stream->rtp_services & sec_serv_conf) { + /* CSRCs are in dst header already, dec in place */ + if (stream->use_cryptex && hdr->cc) { + uint8_t *cc_list = rtp + octets_in_rtp_header; + size_t cc_list_size = hdr->cc * 4; + status = srtp_cipher_decrypt(session_keys->rtp_cipher, cc_list, + cc_list_size, cc_list, &cc_list_size); + if (status) { + return srtp_err_status_cipher_fail; + } + } + status = srtp_cipher_decrypt(session_keys->rtp_cipher, srtp + enc_start, enc_octet_len, rtp + enc_start, &enc_octet_len); @@ -3013,8 +3131,13 @@ srtp_err_status_t srtp_unprotect(srtp_t ctx, } else if (rtp != srtp) { /* if no encryption and not-inplace then need to copy rest of packet */ memcpy(rtp + enc_start, srtp + enc_start, enc_octet_len); -#if 0 + } + if (stream->use_cryptex && hdr->x == 1) { + srtp_clear_cryptex_profile(hdr, rtp); + } + +#if 0 if (use_cryptex) { uint32_t *csrcs = (uint32_t *)hdr + uint32s_in_rtp_header; /* Restore CSRCS to its original position */ @@ -3030,8 +3153,8 @@ srtp_err_status_t srtp_unprotect(srtp_t ctx, return srtp_err_status_parse_err; } } -#endif } +#endif /* * verify that stream is for received traffic - this check will diff --git a/test/srtp_driver.c b/test/srtp_driver.c index 1be8aa07a..f381a6774 100644 --- a/test/srtp_driver.c +++ b/test/srtp_driver.c @@ -706,7 +706,6 @@ int main(int argc, char *argv[]) exit(1); } -#if 0 printf("testing srtp_protect and srtp_unprotect against " "reference cryptex packet\n"); if (srtp_validate_cryptex() == srtp_err_status_ok) { @@ -715,7 +714,6 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } -#endif #ifdef GCM printf("testing srtp_protect and srtp_unprotect against " @@ -727,7 +725,6 @@ int main(int argc, char *argv[]) exit(1); } -#if 0 printf("testing srtp_protect and srtp_unprotect against " "reference cryptex packet using GCM\n"); if (srtp_validate_gcm_cryptex() == srtp_err_status_ok) { @@ -736,7 +733,6 @@ int main(int argc, char *argv[]) printf("failed\n"); exit(1); } -#endif #endif printf("testing srtp_protect and srtp_unprotect against " @@ -2732,7 +2728,7 @@ srtp_err_status_t srtp_validate_null(void) * some computed packets against some pre-computed reference values. * These packets were made with the default SRTP policy. */ -srtp_err_status_t srtp_validate_cryptex() +srtp_err_status_t srtp_validate_cryptex(void) { // clang-format off /* Plaintext packet with 1-byte header extension */ @@ -2923,7 +2919,6 @@ srtp_err_status_t srtp_validate_cryptex() }; srtp_t srtp_snd, srtp_recv; - srtp_err_status_t status; size_t len, ref_len, enc_len; srtp_policy_t policy; @@ -2939,15 +2934,12 @@ srtp_err_status_t srtp_validate_cryptex() policy.key = test_key; policy.window_size = 128; policy.allow_repeat_tx = 0; - policy.use_cryptex = 1; + policy.use_cryptex = true; policy.next = NULL; - status = srtp_create(&srtp_snd, &policy); - if (status) { - return status; - } + CHECK_OK(srtp_create(&srtp_snd, &policy)); - for (int i = 0; i < 6; ++i) { + for (size_t i = 0; i < 6; ++i) { uint8_t packet[1400]; uint8_t reference[1400]; uint8_t ciphertext[1400]; @@ -2969,52 +2961,35 @@ srtp_err_status_t srtp_validate_cryptex() */ debug_print(mod_driver, "test vector: %s\n", vectors[i].name); - status = call_srtp_protect(srtp_snd, packet, &len, 0); - if (status || (len != enc_len)) { - return srtp_err_status_fail; - } + CHECK_OK(call_srtp_protect(srtp_snd, packet, &len, 0)); + CHECK(len == enc_len); debug_print(mod_driver, "ciphertext:\n %s", octet_string_hex_string(packet, len)); debug_print(mod_driver, "ciphertext reference:\n %s", octet_string_hex_string(ciphertext, len)); - if (srtp_octet_string_equal(packet, ciphertext, len)) { - return srtp_err_status_fail; - } + CHECK_BUFFER_EQUAL(packet, ciphertext, len); /* * create a receiver session context comparable to the one created * above - we need to do this so that the replay checking doesn't * complain */ - status = srtp_create(&srtp_recv, &policy); - if (status) { - return status; - } + CHECK_OK(srtp_create(&srtp_recv, &policy)); /* * unprotect ciphertext, then compare with plaintext */ - status = call_srtp_unprotect(srtp_recv, packet, &len); - if (status || (len != ref_len)) { - return status; - } + CHECK_OK(call_srtp_unprotect(srtp_recv, packet, &len)); + CHECK(len == ref_len); - if (srtp_octet_string_equal(packet, reference, len)) { - return srtp_err_status_fail; - } + CHECK_BUFFER_EQUAL(packet, reference, len); - status = srtp_dealloc(srtp_recv); - if (status) { - return status; - } + CHECK_OK(srtp_dealloc(srtp_recv)); } - status = srtp_dealloc(srtp_snd); - if (status) { - return status; - } + CHECK_OK(srtp_dealloc(srtp_snd)); return srtp_err_status_ok; } @@ -3191,7 +3166,7 @@ srtp_err_status_t srtp_validate_gcm(void) * srtp_validate_gcm() verifies the correctness of libsrtp by comparing * an computed packet against the known ciphertext for the plaintext. */ -srtp_err_status_t srtp_validate_gcm_cryptex() +srtp_err_status_t srtp_validate_gcm_cryptex(void) { // clang-format off unsigned char test_key_gcm_cryptex[28] = { @@ -3272,7 +3247,8 @@ srtp_err_status_t srtp_validate_gcm_cryptex() "abababab"; const char *srtp_1bytehdrext_cc_cryptex_gcm = - "920f1238decafbad" + "920f1238" + "decafbad" "cafebabe" "63bbccc4" "a7f695c4" @@ -3396,7 +3372,6 @@ srtp_err_status_t srtp_validate_gcm_cryptex() }; srtp_t srtp_snd, srtp_recv; - srtp_err_status_t status; size_t len, ref_len, enc_len; srtp_policy_t policy; @@ -3412,15 +3387,12 @@ srtp_err_status_t srtp_validate_gcm_cryptex() policy.key = test_key_gcm_cryptex; policy.window_size = 128; policy.allow_repeat_tx = 0; - policy.use_cryptex = 1; + policy.use_cryptex = true; policy.next = NULL; - status = srtp_create(&srtp_snd, &policy); - if (status) { - return status; - } + CHECK_OK(srtp_create(&srtp_snd, &policy)); - for (int i = 0; i < 6; ++i) { + for (int i = 0; i < 2; ++i) { uint8_t packet[1400]; uint8_t reference[1400]; uint8_t ciphertext[1400]; @@ -3442,52 +3414,35 @@ srtp_err_status_t srtp_validate_gcm_cryptex() */ debug_print(mod_driver, "test vector: %s\n", vectors[i].name); - status = call_srtp_protect(srtp_snd, packet, &len, 0); - if (status || (len != enc_len)) { - return srtp_err_status_fail; - } + CHECK_OK(call_srtp_protect(srtp_snd, packet, &len, 0)); + CHECK(len == enc_len); debug_print(mod_driver, "ciphertext:\n %s", octet_string_hex_string(packet, len)); debug_print(mod_driver, "ciphertext reference:\n %s", octet_string_hex_string(ciphertext, len)); - if (srtp_octet_string_equal(packet, ciphertext, len)) { - return srtp_err_status_fail; - } + CHECK_BUFFER_EQUAL(packet, ciphertext, len); /* * create a receiver session context comparable to the one created * above - we need to do this so that the replay checking doesn't * complain */ - status = srtp_create(&srtp_recv, &policy); - if (status) { - return status; - } + CHECK_OK(srtp_create(&srtp_recv, &policy)); /* * unprotect ciphertext, then compare with plaintext */ - status = call_srtp_unprotect(srtp_recv, packet, &len); - if (status || (len != ref_len)) { - return status; - } + CHECK_OK(call_srtp_unprotect(srtp_recv, packet, &len)); + CHECK(len == ref_len); - if (srtp_octet_string_equal(packet, reference, len)) { - return srtp_err_status_fail; - } + CHECK_BUFFER_EQUAL(packet, reference, len); - status = srtp_dealloc(srtp_recv); - if (status) { - return status; - } + CHECK_OK(srtp_dealloc(srtp_recv)); } - status = srtp_dealloc(srtp_snd); - if (status) { - return status; - } + CHECK_OK(srtp_dealloc(srtp_snd)); return srtp_err_status_ok; }