8000 Properly support null crypto and null auth scenario by pabuhler · Pull Request #760 · cisco/libsrtp · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
/ libsrtp Public

Properly support null crypto and null auth scenario #760

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

Open
wants to merge 1 commit into
base: 2_x_dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 27 additions & 6 deletions srtp/srtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,7 @@ static inline int full_key_length(const srtp_cipher_type_t *cipher)
{
switch (cipher->id) {
case SRTP_NULL_CIPHER:
return 0;
case SRTP_AES_ICM_128:
return SRTP_AES_ICM_128_KEY_LEN_WSALT;
case SRTP_AES_ICM_192:
Expand All @@ -862,6 +863,19 @@ static inline int full_key_length(const srtp_cipher_type_t *cipher)
}
}

/* Get the key length that the application should supply for the given auth */
static inline int full_auth_key_length(const srtp_auth_type_t *auth)
{
switch (auth->id) {
case SRTP_NULL_AUTH:
return 0;
case SRTP_HMAC_SHA1:
return SRTP_AES_ICM_128_KEY_LEN_WSALT;
default:
return 0;
}
}

static unsigned int srtp_validate_policy_master_keys(
const srtp_policy_t *policy)
{
Expand Down Expand Up @@ -957,7 +971,7 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
srtp_err_status_t stat;
srtp_kdf_t kdf;
uint8_t tmp_key[MAX_SRTP_KEY_LEN];
int input_keylen, input_keylen_rtcp;
int input_keylen, full_keylen;
int kdf_keylen = 30, rtp_keylen, rtcp_keylen;
int rtp_base_key_len, rtp_salt_len;
int rtcp_base_key_len, rtcp_salt_len;
Expand Down Expand Up @@ -995,9 +1009,17 @@ srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
session_keys->mki_size = master_key->mki_size;

input_keylen = full_key_length(session_keys->rtp_cipher->type);
input_keylen_rtcp = full_key_length(session_keys->rtcp_cipher->type);
if (input_keylen_rtcp > input_keylen) {
input_keylen = input_keylen_rtcp;
full_keylen = full_auth_key_length(session_keys->rtp_auth->type);
if (full_keylen > input_keylen) {
input_keylen = full_keylen;
}
full_keylen = full_key_length(session_keys->rtcp_cipher->type);
if (full_keylen > input_keylen) {
input_keylen = full_keylen;
}
full_keylen = full_auth_key_length(session_keys->rtcp_auth->type);
if (full_keylen > input_keylen) {
input_keylen = full_keylen;
}

rtp_keylen = srtp_cipher_get_key_length(session_keys->rtp_cipher);
Expand Down Expand Up @@ -3410,8 +3432,7 @@ void srtp_crypto_policy_set_null_cipher_hmac_null(srtp_crypto_policy_t *p)
*/

p->cipher_type = SRTP_NULL_CIPHER;
p->cipher_key_len =
SRTP_AES_ICM_128_KEY_LEN_WSALT; /* 128 bit key, 112 bit salt */
p->cipher_key_len = 0;
p->auth_type = SRTP_NULL_AUTH;
p->auth_key_len = 0;
p->auth_tag_len = 0;
Expand Down
195 changes: 188 additions & 7 deletions test/srtp_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@

srtp_err_status_t srtp_validate(void);

srtp_err_status_t srtp_validate_null(void);
srtp_err_status_t srtp_validate_null_sha1_80(void);

srtp_err_status_t srtp_validate_null_null(void);

#ifdef GCM
srtp_err_status_t srtp_validate_gcm(void);
Expand Down Expand Up @@ -458,8 +460,17 @@ int main(int argc, char *argv[])
}

printf("testing srtp_protect and srtp_unprotect against "
"reference packet using null cipher and HMAC\n");
if (srtp_validate_null() == srtp_err_status_ok) {
"reference packet using null cipher and SHA1-80 HMAC\n");
if (srtp_validate_null_sha1_80() == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n");
exit(1);
}

printf("testing srtp_protect and srtp_unprotect against "
"reference packet using null cipher and null HMAC\n");
if (srtp_validate_null_null() == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n");
Expand Down Expand Up @@ -1901,13 +1912,13 @@ srtp_err_status_t srtp_validate(void)
}

/*
* srtp_validate_null() verifies the correctness of libsrtp by comparing
* srtp_validate_null_sha1_80() verifies the correctness of libsrtp by comparing
* some computed packets against some pre-computed reference values.
* These packets were made with a policy that applies null encryption
* and HMAC authentication.
*/

srtp_err_status_t srtp_validate_null(void)
srtp_err_status_t srtp_validate_null_sha1_80(void)
{
// clang-format off
uint8_t srtp_plaintext_ref[28] = {
Expand Down Expand Up @@ -1957,8 +1968,8 @@ srtp_err_status_t srtp_validate_null(void)
srtp_policy_t policy;

/*
* create a session with a single stream using the default srtp
* policy and with the SSRC value 0xcafebabe
* create a session with a single stream using the null cipher
* and sha1_80 policy and with the SSRC value 0xcafebabe
*/
memset(&policy, 0, sizeof(policy));
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
Expand Down Expand Up @@ -2060,6 +2071,176 @@ srtp_err_status_t srtp_validate_null(void)
return srtp_err_status_ok;
}

/*
* srtp_validate_null_null() verifies the correctness of libsrtp by comparing
* some computed packets against some pre-computed reference values.
* These packets were made with a policy that applies null encryption
* and null authentication.
*/

srtp_err_status_t srtp_validate_null_null(void)
{
// clang-format off
uint8_t srtp_plaintext_ref[28] = {
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab
};
uint8_t srtp_plaintext[28] = {
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab,
};
uint8_t srtp_ciphertext[28] = {
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab,
};
uint8_t rtcp_plaintext_ref[24] = {
0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
};
uint8_t rtcp_plaintext[28] = {
0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0x00, 0x00, 0x00, 0x00,
};
uint8_t srtcp_ciphertext[28] = {
0x81, 0xc8, 0x00, 0x0b, 0xca, 0xfe, 0xba, 0xbe,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
0x00, 0x00, 0x00, 0x01,
};
// clang-format on

srtp_t srtp_snd, srtp_recv;
srtp_err_status_t status;
int len;
srtp_policy_t policy;

/*
* create a session with a single stream using the null cipher
* and null hmac policy and with the SSRC value 0xcafebabe
*/
memset(&policy, 0, sizeof(policy));
srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtp);
srtp_crypto_policy_set_null_cipher_hmac_null(&policy.rtcp);
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xcafebabe;
/*
* We need some non-zero value set here
*/
policy.key = (void *)(uintptr_t)-1;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.next = NULL;

status = srtp_create(&srtp_snd, &policy);
if (status) {
return status;
}

/*
* protect plaintext, then compare with ciphertext
*/
len = 28;
status = srtp_protect(srtp_snd, srtp_plaintext, &len);
if (status || (len != 28)) {
return srtp_err_status_fail;
}
if (status) {
return status;
}

debug_print(mod_driver, "ciphertext:\n %s",
octet_string_hex_string(srtp_plaintext, len));
debug_print(mod_driver, "ciphertext reference:\n %s",
octet_string_hex_string(srtp_ciphertext, len));

if (srtp_octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len)) {
return srtp_err_status_fail;
}

/*
* protect plaintext rtcp, then compare with srtcp ciphertext
*/
len = 24;
status = srtp_protect_rtcp(srtp_snd, rtcp_plaintext, &len);
if (!status && (len != 28)) {
status = srtp_err_status_fail;
}
if (status) {
return status;
}

debug_print(mod_driver, "srtcp ciphertext:\n %s",
octet_string_hex_string(rtcp_plaintext, len));
debug_print(mod_driver, "srtcp ciphertext reference:\n %s",
octet_string_hex_string(srtcp_ciphertext, len));

if (srtp_octet_string_is_eq(rtcp_plaintext, srtcp_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, srtp_ciphertext, &len);
if (!status && (len != 28)) {
status = srtp_err_status_fail;
}
if (status) {
return status;
}

if (srtp_octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len)) {
return srtp_err_status_fail;
}

/*
* unprotect srtcp ciphertext, then compare with rtcp plaintext
*/
len = 28;
status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len);
if (!status && (len != 24)) {
status = srtp_err_status_fail;
}
if (status) {
return status;
}

if (srtp_octet_string_is_eq(srtcp_ciphertext, rtcp_plaintext_ref, 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
Expand Down
Loading
0