Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for cryptex #511

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/srtp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
/**< cryptex. */
struct srtp_policy_t *next; /**< Pointer to next stream policy. */
} srtp_policy_t;

Expand Down
1 change: 1 addition & 0 deletions include/srtp_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
struct srtp_stream_ctx_t_ *next; /* linked list of streams */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

next was removed, I guess this slipped in while merging ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There have been a lot of changes in main, are you sure the merge went well ? All builds are failing.
Also the input buffer to the protect/unprotect functions is now const, not sure you should just cast that away and move the memory around.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think I have been too optimistic about my rebasing 😅

Wil try to get a look next week

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I had a quick attempt a few weeks ago and understood that this was not an easy merge :( . Let me know if you want to discuss anything.

} strp_stream_ctx_t_;

Expand Down
218 changes: 182 additions & 36 deletions srtp/srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -1698,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");

Expand Down Expand Up @@ -1727,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 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];
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);
}
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
}
/* note: the passed size is without the auth tag */
if (!((uint8_t *)enc_start <= (uint8_t *)hdr + *pkt_octet_len))
Expand Down Expand Up @@ -1812,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*/
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down Expand Up @@ -1859,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;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
int xtn_profile_specific = 0;
unsigned int use_cryptex = 0;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved

debug_print0(mod_srtp, "function srtp_unprotect_aead");

Expand Down Expand Up @@ -1900,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)))
Expand Down Expand Up @@ -1959,6 +2018,22 @@ static srtp_err_status_t srtp_unprotect_aead(srtp_ctx_t *ctx,
return status;
}

if (use_cryptex) {
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*/
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down Expand Up @@ -2060,6 +2135,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;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
int xtn_profile_specific = 0;

debug_print0(mod_srtp, "function srtp_protect");

Expand Down Expand Up @@ -2169,10 +2246,28 @@ 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 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 */
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
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))
Expand Down Expand Up @@ -2319,6 +2414,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) {
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;
}
}
}

/*
Expand Down Expand Up @@ -2390,6 +2501,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;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved
int xtn_profile_specific = 0;
unsigned int use_cryptex = 0;
murillo128 marked this conversation as resolved.
Show resolved Hide resolved

debug_print0(mod_srtp, "function srtp_unprotect");

Expand Down Expand Up @@ -2538,29 +2652,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
Expand Down Expand Up @@ -2622,6 +2713,45 @@ 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) {
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)))
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
Expand Down Expand Up @@ -2654,6 +2784,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) {
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 == 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;
}
}
}

/*
Expand Down
Loading