1 /*
2  * srtp_priv.h
3  *
4  * private internal data structures and functions for libSRTP
5  *
6  * David A. McGrew
7  * Cisco Systems, Inc.
8  */
9 /*
10  *
11  * Copyright (c) 2001-2017 Cisco Systems, Inc.
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  *
18  *   Redistributions of source code must retain the above copyright
19  *   notice, this list of conditions and the following disclaimer.
20  *
21  *   Redistributions in binary form must reproduce the above
22  *   copyright notice, this list of conditions and the following
23  *   disclaimer in the documentation and/or other materials provided
24  *   with the distribution.
25  *
26  *   Neither the name of the Cisco Systems, Inc. nor the names of its
27  *   contributors may be used to endorse or promote products derived
28  *   from this software without specific prior written permission.
29  *
30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
35  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
41  * OF THE POSSIBILITY OF SUCH DAMAGE.
42  *
43  */
44 
45 #ifndef SRTP_PRIV_H
46 #define SRTP_PRIV_H
47 
48 // Leave this as the top level import. Ensures the existence of defines
49 #include "config.h"
50 
51 #include "srtp.h"
52 #include "rdbx.h"
53 #include "rdb.h"
54 #include "integers.h"
55 #include "cipher.h"
56 #include "auth.h"
57 #include "aes.h"
58 #include "key.h"
59 #include "crypto_kernel.h"
60 
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64 
65 #define SRTP_VER_STRING PACKAGE_STRING
66 #define SRTP_VERSION PACKAGE_VERSION
67 
68 typedef struct srtp_stream_ctx_t_ srtp_stream_ctx_t;
69 typedef srtp_stream_ctx_t *srtp_stream_t;
70 
71 /*
72  * the following declarations are libSRTP internal functions
73  */
74 
75 /*
76  * srtp_get_stream(ssrc) returns a pointer to the stream corresponding
77  * to ssrc, or NULL if no stream exists for that ssrc
78  */
79 srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
80 
81 /*
82  * srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by
83  * deriving all of the needed keys using the KDF and the key k.
84  */
85 srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
86                                         srtp_master_key_t *master_key,
87                                         const unsigned int current_mki_index);
88 
89 /*
90  * srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s
91  * by deriving all of the needed keys for all the master keys using the KDF and
92  * the keys from k.
93  */
94 srtp_err_status_t srtp_steam_init_all_master_keys(
95     srtp_stream_ctx_t *srtp,
96     unsigned char *key,
97     srtp_master_key_t **keys,
98     const unsigned int max_master_keys);
99 
100 /*
101  * srtp_stream_init(s, p) initializes the srtp_stream_t s to
102  * use the policy at the location p
103  */
104 srtp_err_status_t srtp_stream_init(srtp_stream_t srtp, const srtp_policy_t *p);
105 
106 /*
107  * libsrtp internal datatypes
108  */
109 typedef enum direction_t {
110     dir_unknown = 0,
111     dir_srtp_sender = 1,
112     dir_srtp_receiver = 2
113 } direction_t;
114 
115 /*
116  * srtp_session_keys_t will contain the encryption, hmac, salt keys
117  * for both SRTP and SRTCP.  The session keys will also contain the
118  * MKI ID which is used to identify the session keys.
119  */
120 typedef struct srtp_session_keys_t {
121     srtp_cipher_t *rtp_cipher;
122     srtp_cipher_t *rtp_xtn_hdr_cipher;
123     srtp_auth_t *rtp_auth;
124     srtp_cipher_t *rtcp_cipher;
125     srtp_auth_t *rtcp_auth;
126     uint8_t salt[SRTP_AEAD_SALT_LEN];
127     uint8_t c_salt[SRTP_AEAD_SALT_LEN];
128     uint8_t *mki_id;
129     unsigned int mki_size;
130     srtp_key_limit_ctx_t *limit;
131 } srtp_session_keys_t;
132 
133 /*
134  * an srtp_stream_t has its own SSRC, encryption key, authentication
135  * key, sequence number, and replay database
136  *
137  * note that the keys might not actually be unique, in which case the
138  * srtp_cipher_t and srtp_auth_t pointers will point to the same structures
139  */
140 typedef struct srtp_stream_ctx_t_ {
141     uint32_t ssrc;
142     srtp_session_keys_t *session_keys;
143     unsigned int num_master_keys;
144     srtp_rdbx_t rtp_rdbx;
145     srtp_sec_serv_t rtp_services;
146     srtp_rdb_t rtcp_rdb;
147     srtp_sec_serv_t rtcp_services;
148     direction_t direction;
149     int allow_repeat_tx;
150     srtp_ekt_stream_t ekt;
151     int *enc_xtn_hdr;
152     int enc_xtn_hdr_count;
153     uint32_t pending_roc;
154     struct srtp_stream_ctx_t_ *next; /* linked list of streams */
155 } strp_stream_ctx_t_;
156 
157 /*
158  * an srtp_ctx_t holds a stream list and a service description
159  */
160 typedef struct srtp_ctx_t_ {
161     struct srtp_stream_ctx_t_ *stream_list;     /* linked list of streams     */
162     struct srtp_stream_ctx_t_ *stream_template; /* act as template for other  */
163                                                 /* streams                    */
164     void *user_data;                            /* user custom data           */
165 } srtp_ctx_t_;
166 
167 /*
168  * srtp_hdr_t represents an RTP or SRTP header.  The bit-fields in
169  * this structure should be declared "unsigned int" instead of
170  * "unsigned char", but doing so causes the MS compiler to not
171  * fully pack the bit fields.
172  *
173  * In this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
174  *
175  * (note that this definition follows that of RFC 1889 Appendix A, but
176  * is not identical)
177  */
178 
179 #ifndef WORDS_BIGENDIAN
180 
181 typedef struct {
182     unsigned char cc : 4;      /* CSRC count             */
183     unsigned char x : 1;       /* header extension flag  */
184     unsigned char p : 1;       /* padding flag           */
185     unsigned char version : 2; /* protocol version       */
186     unsigned char pt : 7;      /* payload type           */
187     unsigned char m : 1;       /* marker bit             */
188     uint16_t seq;              /* sequence number        */
189     uint32_t ts;               /* timestamp              */
190     uint32_t ssrc;             /* synchronization source */
191 } srtp_hdr_t;
192 
193 #else /*  BIG_ENDIAN */
194 
195 typedef struct {
196     unsigned char version : 2; /* protocol version       */
197     unsigned char p : 1;       /* padding flag           */
198     unsigned char x : 1;       /* header extension flag  */
199     unsigned char cc : 4;      /* CSRC count             */
200     unsigned char m : 1;       /* marker bit             */
201     unsigned char pt : 7;      /* payload type           */
202     uint16_t seq;              /* sequence number        */
203     uint32_t ts;               /* timestamp              */
204     uint32_t ssrc;             /* synchronization source */
205 } srtp_hdr_t;
206 
207 #endif
208 
209 typedef struct {
210     uint16_t profile_specific; /* profile-specific info               */
211     uint16_t length;           /* number of 32-bit words in extension */
212 } srtp_hdr_xtnd_t;
213 
214 /*
215  * srtcp_hdr_t represents a secure rtcp header
216  *
217  * in this implementation, an srtcp header is assumed to be 32-bit
218  * alinged
219  */
220 
221 #ifndef WORDS_BIGENDIAN
222 
223 typedef struct {
224     unsigned char rc : 5;      /* reception report count */
225     unsigned char p : 1;       /* padding flag           */
226     unsigned char version : 2; /* protocol version       */
227     unsigned char pt : 8;      /* payload type           */
228     uint16_t len;              /* length                 */
229     uint32_t ssrc;             /* synchronization source */
230 } srtcp_hdr_t;
231 
232 typedef struct {
233     unsigned int index : 31; /* srtcp packet index in network order!  */
234     unsigned int e : 1;      /* encrypted? 1=yes                      */
235                              /* optional mikey/etc go here            */
236                              /* and then the variable-length auth tag */
237 } srtcp_trailer_t;
238 
239 #else /*  BIG_ENDIAN */
240 
241 typedef struct {
242     unsigned char version : 2; /* protocol version       */
243     unsigned char p : 1;       /* padding flag           */
244     unsigned char rc : 5;      /* reception report count */
245     unsigned char pt : 8;      /* payload type           */
246     uint16_t len;              /* length                 */
247     uint32_t ssrc;             /* synchronization source */
248 } srtcp_hdr_t;
249 
250 typedef struct {
251     unsigned int e : 1;      /* encrypted? 1=yes                      */
252     unsigned int index : 31; /* srtcp packet index                    */
253                              /* optional mikey/etc go here            */
254                              /* and then the variable-length auth tag */
255 } srtcp_trailer_t;
256 
257 #endif
258 
259 /*
260  * srtp_handle_event(srtp, srtm, evnt) calls the event handling
261  * function, if there is one.
262  *
263  * This macro is not included in the documentation as it is
264  * an internal-only function.
265  */
266 
267 #define srtp_handle_event(srtp, strm, evnt)                                    \
268     if (srtp_event_handler) {                                                  \
269         srtp_event_data_t data;                                                \
270         data.session = srtp;                                                   \
271         data.ssrc = ntohl(strm->ssrc);                                         \
272         data.event = evnt;                                                     \
273         srtp_event_handler(&data);                                             \
274     }
275 
276 #ifdef __cplusplus
277 }
278 #endif
279 
280 #endif /* SRTP_PRIV_H */
281