/* * srtp_driver.c * * a test driver for libSRTP * * David A. McGrew * Cisco Systems, Inc.
*/ /* * * Copyright (c) 2001-2017, Cisco Systems, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the Cisco Systems, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. *
*/
#include <string.h> /* for memcpy() */ #include <time.h> /* for clock() */ #include <stdlib.h> /* for malloc(), free() */ #include <stdio.h> /* for print(), fflush() */ #include"getopt_s.h"/* for local getopt() */
/* the wildcard_policy is declared below; it has a wildcard ssrc */
externconst srtp_policy_t wildcard_policy;
/* * mod_driver debug module - debugging module for this test driver * * we use the crypto_kernel debugging system in this driver, which * makes the interface uniform and increases portability
*/
srtp_debug_module_t mod_driver = {
0, /* debugging is off by default */ "driver"/* printable name for module */
};
/* * verify that the compiler has interpreted the header data * structure srtp_hdr_t correctly
*/ if (sizeof(srtp_hdr_t) != 12) {
printf("error: srtp_hdr_t has incorrect size" "(size is %ld bytes, expected 12)\n",
(long)sizeof(srtp_hdr_t)); exit(1);
}
/* initialize srtp library */
status = srtp_init(); if (status) {
printf("error: srtp init failed with error code %d\n", status); exit(1);
}
/* load srtp_driver debug module */
status = srtp_crypto_kernel_load_debug_module(&mod_driver); if (status) {
printf("error: load of srtp_driver debug module failed " "with error code %d\n",
status); exit(1);
}
/* loop over policy array, testing srtp and srtcp for each policy */ while (*policy != NULL) {
printf("testing srtp_protect and srtp_unprotect\n"); if (srtp_test(*policy, 0, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect and srtp_unprotect with encrypted " "extensions headers\n"); if (srtp_test(*policy, 1, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n"); if (srtcp_test(*policy, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI " "index set to 0\n"); if (srtp_test(*policy, 0, 0) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect_rtp and srtp_unprotect_rtp with MKI " "index set to 1\n"); if (srtp_test(*policy, 0, 1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI " "index set to 0\n"); if (srtcp_test(*policy, 0) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp with MKI " "index set to 1\n"); if (srtcp_test(*policy, 1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
policy++;
}
/* loop over invalid policy array, testing that an SRTP context cannot
* be created with the policy */
policy = invalid_policy_array; while (*policy != NULL) {
printf("testing srtp_create fails with invalid policy\n"); if (srtp_create(&srtp_sender, *policy) != srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
policy++;
}
/* create a big policy list and run tests on it */
status = srtp_create_big_policy(&big_policy); if (status) {
printf("unexpected failure with error code %d\n", status); exit(1);
}
printf("testing srtp_protect and srtp_unprotect with big policy\n"); if (srtp_test(big_policy, 0, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect and srtp_unprotect with big policy and " "encrypted extensions headers\n"); if (srtp_test(big_policy, 1, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
status = srtp_dealloc_big_policy(big_policy); if (status) {
printf("unexpected failure with error code %d\n", status); exit(1);
}
/* run test on wildcard policy */
printf("testing srtp_protect and srtp_unprotect on " "wildcard ssrc policy\n"); if (srtp_test(&wildcard_policy, 0, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
printf("testing srtp_protect and srtp_unprotect on " "wildcard ssrc policy and encrypted extensions headers\n"); if (srtp_test(&wildcard_policy, 1, -1) == srtp_err_status_ok) {
printf("passed\n\n");
} else {
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 packet\n"); if (srtp_validate() == 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 HMAC\n"); if (srtp_validate_null() == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
#ifdef GCM
printf("testing srtp_protect and srtp_unprotect against " "reference packet using GCM\n"); if (srtp_validate_gcm() == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
} #endif
printf("testing srtp_protect and srtp_unprotect against " "reference packet with encrypted extensions headers\n"); if (srtp_validate_encrypted_extensions_headers() == srtp_err_status_ok)
printf("passed\n\n"); else {
printf("failed\n"); exit(1);
}
#ifdef GCM
printf("testing srtp_protect and srtp_unprotect against " "reference packet with encrypted extension headers (GCM)\n"); if (srtp_validate_encrypted_extensions_headers_gcm() ==
srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
} #endif
/* * run validation test against the reference packets for * AES-256
*/
printf("testing srtp_protect and srtp_unprotect against " "reference packet (AES-256)\n"); if (srtp_validate_aes_256() == srtp_err_status_ok) {
printf("passed\n\n");
} else {
printf("failed\n"); exit(1);
}
/* * test packets with empty payload
*/
printf("testing srtp_protect and srtp_unprotect against " "packet with empty payload\n"); if (srtp_test_empty_payload() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n"); exit(1);
} #ifdef GCM
printf("testing srtp_protect and srtp_unprotect against " "packet with empty payload (GCM)\n"); if (srtp_test_empty_payload_gcm() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n"); exit(1);
} #endif
/* * test the function srtp_remove_stream()
*/
printf("testing srtp_remove_stream()..."); if (srtp_test_remove_stream() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n"); exit(1);
}
/* * test the function srtp_update()
*/
printf("testing srtp_update()..."); if (srtp_test_update() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n"); exit(1);
}
/* * test the functions srtp_get_protect_trailer_length * and srtp_get_protect_rtcp_trailer_length
*/
printf("testing srtp_get_protect_trailer_length()..."); if (srtp_test_protect_trailer_length() == srtp_err_status_ok) {
printf("passed\n");
} else {
printf("failed\n"); exit(1);
}
if (do_timing_test) { const srtp_policy_t **policy = policy_array;
/* loop over policies, run timing test for each */ while (*policy != NULL) {
srtp_print_policy(*policy);
srtp_do_timing(*policy);
policy++;
}
}
if (do_rejection_test) { const srtp_policy_t **policy = policy_array;
/* loop over policies, run rejection timing test for each */ while (*policy != NULL) {
srtp_print_policy(*policy);
srtp_do_rejection_timing(*policy);
policy++;
}
}
if (do_codec_timing) {
srtp_policy_t policy; int ignore; double mips_value = mips_estimate(1000000000, &ignore);
status = srtp_shutdown(); if (status) {
printf("error: srtp shutdown failed with error code %d\n", status); exit(1);
}
return 0;
}
/* * srtp_create_test_packet(len, ssrc) returns a pointer to a * (malloced) example RTP packet whose data field has the length given * by pkt_octet_len and the SSRC value ssrc. The total length of the * packet is twelve octets longer, since the header is at the * beginning. There is room at the end of the packet for a trailer, * and the four octets following the packet are filled with 0xff * values to enable testing for overwrites. * * note that the location of the test packet can (and should) be * deallocated with the free() call once it is no longer needed.
*/
srtp_hdr_t *srtp_create_test_packet(int pkt_octet_len,
uint32_t ssrc, int *pkt_len)
{ int i;
uint8_t *buffer;
srtp_hdr_t *hdr; int bytes_in_hdr = 12;
/* allocate memory for test packet */
hdr = (srtp_hdr_t *)malloc(pkt_octet_len + bytes_in_hdr +
SRTP_MAX_TRAILER_LEN + 4); if (!hdr) { return NULL;
}
hdr->version = 2; /* RTP version two */
hdr->p = 0; /* no padding needed */
hdr->x = 0; /* no header extension */
hdr->cc = 0; /* no CSRCs */
hdr->m = 0; /* marker bit */
hdr->pt = 0xf; /* payload type */
hdr->seq = htons(0x1234); /* sequence number */
hdr->ts = htonl(0xdecafbad); /* timestamp */
hdr->ssrc = htonl(ssrc); /* synch. source */
buffer = (uint8_t *)hdr;
buffer += bytes_in_hdr;
/* set RTP data to 0xab */ for (i = 0; i < pkt_octet_len; i++) {
*buffer++ = 0xab;
}
/* set post-data value to 0xffff to enable overrun checking */ for (i = 0; i < SRTP_MAX_TRAILER_LEN + 4; i++) {
*buffer++ = 0xff;
}
for (len = 8; len <= 2048; len *= 2) {
printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
}
/* these extra linefeeds let gnuplot know that a dataset is done */
printf("\r\n\r\n");
}
#define MAX_MSG_LEN 1024
double srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy)
{
srtp_t srtp;
srtp_hdr_t *mesg; int i;
clock_t timer; int num_trials = 100000; int input_len, len;
uint32_t ssrc;
srtp_err_status_t status;
/* * allocate and initialize an srtp session
*/
status = srtp_create(&srtp, policy); if (status) {
printf("error: srtp_create() failed with error code %d\n", status); exit(1);
}
/* * if the ssrc is unspecified, use a predetermined one
*/ if (policy->ssrc.type != ssrc_specific) {
ssrc = 0xdeadbeef;
} else {
ssrc = policy->ssrc.value;
}
/* * create a test packet
*/
mesg = srtp_create_test_packet(msg_len_octets, ssrc, &input_len); if (mesg == NULL) { return 0.0; /* indicate failure by returning zero */
}
timer = clock(); for (i = 0; i < num_trials; i++) {
len = input_len; /* srtp protect message */
status = srtp_protect(srtp, mesg, &len); if (status) {
printf("error: srtp_protect() failed with error code %d\n", status); exit(1);
}
/* increment message number */
{ /* hack sequence to avoid problems with macros for htons/ntohs on
* some systems */ short new_seq = ntohs(mesg->seq) + 1;
mesg->seq = htons(new_seq);
}
}
timer = clock() - timer;
free(mesg);
status = srtp_dealloc(srtp); if (status) {
printf("error: srtp_dealloc() failed with error code %d\n", status); exit(1);
}
/* print out policy */
err_check(srtp_session_print_policy(srtp_sender));
/* * initialize data buffer, using the ssrc in the policy unless that * value is a wildcard, in which case we'll just use an arbitrary * one
*/ if (policy->ssrc.type != ssrc_specific) {
ssrc = 0xdecafbad;
} else {
ssrc = policy->ssrc.value;
}
msg_len_octets = 28; if (extension_header) {
hdr = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len);
hdr2 = srtp_create_test_packet_ext_hdr(msg_len_octets, ssrc, &len2);
} else {
hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len);
hdr2 = srtp_create_test_packet(msg_len_octets, ssrc, &len2);
}
/* save original msg len */
msg_len = len;
if (hdr == NULL) {
free(hdr2); return srtp_err_status_alloc_fail;
} if (hdr2 == NULL) {
free(hdr); return srtp_err_status_alloc_fail;
}
/* save protected message and length */
memcpy(hdr_enc, hdr, len);
msg_len_enc = len;
/* * check for overrun of the srtp_protect() function * * The packet is followed by a value of 0xfffff; if the value of the * data following the packet is different, then we know that the * protect function is overwriting the end of the packet.
*/
err_check(srtp_get_protect_trailer_length(srtp_sender, use_mki, mki_index,
&tag_length));
pkt_end = (uint8_t *)hdr + msg_len + tag_length; for (i = 0; i < 4; i++) { if (pkt_end[i] != 0xff) {
fprintf(stdout, "overwrite in srtp_protect() function " "(expected %x, found %x in trailing octet %d)\n",
0xff, ((uint8_t *)hdr)[i], i);
free(hdr);
free(hdr2); return srtp_err_status_algo_fail;
}
}
/* * if the policy includes confidentiality, check that ciphertext is * different than plaintext * * Note that this check will give false negatives, with some small * probability, especially if the packets are short. For that * reason, we skip this check if the plaintext is less than four * octets long.
*/ if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
printf("testing that ciphertext is distinct from plaintext...");
status = srtp_err_status_algo_fail; for (i = 12; i < msg_len_octets + 12; i++) { if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
status = srtp_err_status_ok;
}
} if (status) {
printf("failed\n");
free(hdr);
free(hdr2); return status;
}
printf("passed\n");
}
/* * if the policy uses a 'wildcard' ssrc, then we need to make a copy * of the policy that changes the direction to inbound * * we always copy the policy into the rcvr_policy, since otherwise * the compiler would fret about the constness of the policy
*/
rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t)); if (rcvr_policy == NULL) {
free(hdr);
free(hdr2); return srtp_err_status_alloc_fail;
} if (extension_header) {
memcpy(rcvr_policy, &tmp_policy, sizeof(srtp_policy_t)); if (tmp_policy.ssrc.type == ssrc_any_outbound) {
rcvr_policy->ssrc.type = ssrc_any_inbound;
}
} else {
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); if (policy->ssrc.type == ssrc_any_outbound) {
rcvr_policy->ssrc.type = ssrc_any_inbound;
}
}
/* verify that the unprotected packet matches the origial one */ for (i = 0; i < len; i++) { if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
fprintf(stdout, "mismatch at octet %d\n", i);
status = srtp_err_status_algo_fail;
}
} if (status) {
free(hdr);
free(hdr2);
free(rcvr_policy); return status;
}
/* * if the policy includes authentication, then test for false positives
*/ if (policy->rtp.sec_serv & sec_serv_auth) { char *data = ((char *)hdr) + (extension_header ? 24 : 12);
printf("testing for false positives in replay check...");
/* unprotect a second time - should fail with a replay error */
status =
srtp_test_call_unprotect(srtp_rcvr, hdr, &msg_len_enc, use_mki); if (status != srtp_err_status_replay_fail) {
printf("failed with error code %d\n", status);
free(hdr);
free(hdr2);
free(rcvr_policy); return status;
} else {
printf("passed\n");
}
printf("testing for false positives in auth check...");
/* increment sequence number in header */
hdr->seq++;
srtp_err_status_t srtcp_test(const srtp_policy_t *policy, int mki_index)
{ int i;
srtp_t srtcp_sender;
srtp_t srtcp_rcvr;
srtp_err_status_t status = srtp_err_status_ok;
srtp_hdr_t *hdr, *hdr2;
uint8_t hdr_enc[64];
uint8_t *pkt_end; int msg_len_octets, msg_len_enc, msg_len; int len, len2;
uint32_t tag_length;
uint32_t ssrc;
srtp_policy_t *rcvr_policy; int use_mki = 0;
if (mki_index >= 0)
use_mki = 1;
err_check(srtp_create(&srtcp_sender, policy));
/* print out policy */
err_check(srtp_session_print_policy(srtcp_sender));
/* * initialize data buffer, using the ssrc in the policy unless that * value is a wildcard, in which case we'll just use an arbitrary * one
*/ if (policy->ssrc.type != ssrc_specific) {
ssrc = 0xdecafbad;
} else {
ssrc = policy->ssrc.value;
}
msg_len_octets = 28;
hdr = srtp_create_test_packet(msg_len_octets, ssrc, &len); /* save message len */
msg_len = len;
/* save protected message and length */
memcpy(hdr_enc, hdr, len);
msg_len_enc = len;
/* * check for overrun of the srtp_protect() function * * The packet is followed by a value of 0xfffff; if the value of the * data following the packet is different, then we know that the * protect function is overwriting the end of the packet.
*/
srtp_get_protect_rtcp_trailer_length(srtcp_sender, use_mki, mki_index,
&tag_length);
pkt_end = (uint8_t *)hdr + msg_len + tag_length; for (i = 0; i < 4; i++) { if (pkt_end[i] != 0xff) {
fprintf(stdout, "overwrite in srtp_protect_rtcp() function " "(expected %x, found %x in trailing octet %d)\n",
0xff, ((uint8_t *)hdr)[i], i);
free(hdr);
free(hdr2); return srtp_err_status_algo_fail;
}
}
/* * if the policy includes confidentiality, check that ciphertext is * different than plaintext * * Note that this check will give false negatives, with some small * probability, especially if the packets are short. For that * reason, we skip this check if the plaintext is less than four * octets long.
*/ if ((policy->rtcp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
printf("testing that ciphertext is distinct from plaintext...");
status = srtp_err_status_algo_fail; for (i = 12; i < msg_len_octets + 12; i++) { if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
status = srtp_err_status_ok;
}
} if (status) {
printf("failed\n");
free(hdr);
free(hdr2); return status;
}
printf("passed\n");
}
/* * if the policy uses a 'wildcard' ssrc, then we need to make a copy * of the policy that changes the direction to inbound * * we always copy the policy into the rcvr_policy, since otherwise * the compiler would fret about the constness of the policy
*/
rcvr_policy = (srtp_policy_t *)malloc(sizeof(srtp_policy_t)); if (rcvr_policy == NULL) {
free(hdr);
free(hdr2); return srtp_err_status_alloc_fail;
}
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t)); if (policy->ssrc.type == ssrc_any_outbound) {
rcvr_policy->ssrc.type = ssrc_any_inbound;
}
/* verify that the unprotected packet matches the origial one */ for (i = 0; i < len; i++) { if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
fprintf(stdout, "mismatch at octet %d\n", i);
status = srtp_err_status_algo_fail;
}
} if (status) {
free(hdr);
free(hdr2);
free(rcvr_policy); return status;
}
/* * if the policy includes authentication, then test for false positives
*/ if (policy->rtp.sec_serv & sec_serv_auth) { char *data = ((char *)hdr) + 12;
printf("testing for false positives in replay check...");
/* unprotect a second time - should fail with a replay error */
status = srtp_test_call_unprotect_rtcp(srtcp_rcvr, hdr, &msg_len_enc,
use_mki); if (status != srtp_err_status_replay_fail) {
printf("failed with error code %d\n", status);
free(hdr);
free(hdr2);
free(rcvr_policy); return status;
} else {
printf("passed\n");
}
printf("testing for false positives in auth check...");
/* increment sequence number in header */
hdr->seq++;
printf("# Encrypted extension headers: "); if (stream->enc_xtn_hdr && stream->enc_xtn_hdr_count > 0) { int *enc_xtn_hdr = stream->enc_xtn_hdr; int count = stream->enc_xtn_hdr_count; while (count > 0) {
printf("%d ", *enc_xtn_hdr);
enc_xtn_hdr++;
count--;
}
printf("\n");
} else {
printf("none\n");
}
}
/* loop over streams in session, printing the policy of each */
stream = srtp->stream_list; while (stream != NULL) { if (stream->rtp_services > sec_serv_conf_and_auth) { return srtp_err_status_bad_param;
}
session_keys = &stream->session_keys[0];
/* * mips_estimate() is a simple function to estimate the number of * instructions per second that the host can perform. note that this * function can be grossly wrong; you may want to have a manual sanity * check of its output! * * the 'ignore' pointer is there to convince the compiler to not just * optimize away the function
*/
double mips_estimate(int num_trials, int *ignore)
{
clock_t t; volatileint i, sum;
sum = 0;
t = clock(); for (i = 0; i < num_trials; i++) {
sum += i;
}
t = clock() - t; if (t < 1) {
t = 1;
}
/* printf("%d\n", sum); */
*ignore = sum;
return (double)num_trials * CLOCKS_PER_SEC / t;
}
/* * srtp_validate() 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.
*/
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 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.deprecated_ekt = NULL;
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 != 38)) { return srtp_err_status_fail;
}
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)) { 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 = 38;
status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len); if (status || (len != 24)) { 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;
}
/* * srtp_validate_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 HMAC authentication.
*/
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 default srtp * policy and with the SSRC value 0xcafebabe
*/
memset(&policy, 0, sizeof(policy));
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
srtp_crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtcp);
policy.ssrc.type = ssrc_specific;
policy.ssrc.value = 0xcafebabe;
policy.key = test_key;
policy.deprecated_ekt = NULL;
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 != 38)) { return srtp_err_status_fail;
}
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)) { 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 = 38;
status = srtp_unprotect_rtcp(srtp_recv, srtcp_ciphertext, &len); if (status || (len != 24)) { 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;
}
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 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.deprecated_ekt = NULL;
policy.window_size = 128;
policy.allow_repeat_tx = 0;
policy.next = NULL;
status = srtp_create(&srtp_snd, &policy); if (status) { return status;
}
/* * protect plaintext rtp, then compare with srtp ciphertext
*/
len = 28;
status = srtp_protect(srtp_snd, rtp_plaintext, &len); if (status || (len != 44)) { return srtp_err_status_fail;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.