1 /*
2 * test_srtp.c
3 *
4 * Unit tests for internal srtp functions
5 *
6 * Cisco Systems, Inc.
7 *
8 */
9
10 /*
11 *
12 * Copyright (c) 2017, Cisco Systems, Inc.
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 *
22 * Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials provided
25 * with the distribution.
26 *
27 * Neither the name of the Cisco Systems, Inc. nor the names of its
28 * contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
42 * OF THE POSSIBILITY OF SUCH DAMAGE.
43 *
44 */
45
46 /*
47 * libSRTP specific.
48 */
49 #include "../srtp/srtp.c" // Get access to static functions
50
51 /*
52 * Test specific.
53 */
54 #include "cutest.h"
55
56 /*
57 * Standard library.
58 */
59
60 /*
61 * Forward declarations for all tests.
62 */
63
64 void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output(void);
65 void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param(void);
66 void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number(void);
67
68 /*
69 * NULL terminated array of tests.
70 * The first item in the array is a char[] which give some information about
71 * what is being tested and is displayed to the user during runtime, the second
72 * item is the test function.
73 */
74
75 TEST_LIST = { { "srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()",
76 srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output },
77 { "srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()",
78 srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param },
79 { "srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()",
80 srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number },
81 { NULL } /* End of tests */ };
82
83 /*
84 * Implementation.
85 */
86
srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()87 void srtp_calc_aead_iv_srtcp_all_zero_input_yield_zero_output()
88 {
89 // Preconditions
90 srtp_session_keys_t session_keys;
91 v128_t init_vector;
92 srtcp_hdr_t header;
93 uint32_t sequence_num;
94
95 // Postconditions
96 srtp_err_status_t status;
97 const v128_t zero_vector;
98 memset((v128_t *)&zero_vector, 0, sizeof(v128_t));
99
100 // Given
101 memset(&session_keys, 0, sizeof(srtp_session_keys_t));
102 memset(&init_vector, 0, sizeof(v128_t));
103 memset(&header, 0, sizeof(srtcp_hdr_t));
104 sequence_num = 0x0UL;
105
106 // When
107 status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
108 &header);
109
110 // Then
111 TEST_CHECK(status == srtp_err_status_ok);
112 TEST_CHECK(memcmp(&zero_vector, &init_vector, sizeof(v128_t)) == 0);
113 }
114
srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()115 void srtp_calc_aead_iv_srtcp_seq_num_over_0x7FFFFFFF_bad_param()
116 {
117 // Preconditions
118 srtp_session_keys_t session_keys;
119 v128_t init_vector;
120 srtcp_hdr_t header;
121 uint32_t sequence_num;
122
123 // Postconditions
124 srtp_err_status_t status;
125
126 // Given
127 memset(&session_keys, 0, sizeof(srtp_session_keys_t));
128 memset(&init_vector, 0, sizeof(v128_t));
129 memset(&header, 0, sizeof(srtcp_hdr_t));
130 sequence_num = 0x7FFFFFFFUL + 0x1UL;
131
132 // When
133 status = srtp_calc_aead_iv_srtcp(&session_keys, &init_vector, sequence_num,
134 &header);
135
136 // Then
137 TEST_CHECK(status == srtp_err_status_bad_param);
138 }
139
140 /*
141 * Regression test for issue #256:
142 * Srtcp IV calculation incorrectly masks high bit of sequence number for
143 * little-endian platforms.
144 * Ensure that for each valid sequence number where the most significant bit is
145 * high that we get an expected and unique IV.
146 */
srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()147 void srtp_calc_aead_iv_srtcp_distinct_iv_per_sequence_number()
148 {
149 #define SAMPLE_COUNT (3)
150 // Preconditions
151 // Test each significant bit high in each full byte.
152 srtp_session_keys_t session_keys;
153 srtcp_hdr_t header;
154 v128_t output_iv[SAMPLE_COUNT];
155 uint32_t sequence_num[SAMPLE_COUNT];
156 v128_t final_iv[SAMPLE_COUNT];
157 size_t i = 0;
158 memset(&output_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
159 sequence_num[0] = 0xFF;
160 sequence_num[1] = 0xFF00;
161 sequence_num[2] = 0xFF0000;
162
163 // Postconditions
164 memset(&final_iv, 0, SAMPLE_COUNT * sizeof(v128_t));
165 final_iv[0].v8[11] = 0xFF;
166 final_iv[1].v8[10] = 0xFF;
167 final_iv[2].v8[9] = 0xFF;
168
169 // Given
170 memset(&session_keys, 0, sizeof(srtp_session_keys_t));
171 memset(&header, 0, sizeof(srtcp_hdr_t));
172
173 // When
174 for (i = 0; i < SAMPLE_COUNT; i++) {
175 TEST_CHECK(srtp_calc_aead_iv_srtcp(&session_keys, &output_iv[i],
176 sequence_num[i],
177 &header) == srtp_err_status_ok);
178 }
179
180 // Then all IVs are as expected
181 for (i = 0; i < SAMPLE_COUNT; i++) {
182 TEST_CHECK(memcmp(&final_iv[i], &output_iv[i], sizeof(v128_t)) == 0);
183 }
184 #undef SAMPLE_COUNT
185 }
186