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