michael@0: /* michael@0: * srtp_priv.h michael@0: * michael@0: * private internal data structures and functions for libSRTP michael@0: * michael@0: * David A. McGrew michael@0: * Cisco Systems, Inc. michael@0: */ michael@0: /* michael@0: * michael@0: * Copyright (c) 2001-2006 Cisco Systems, Inc. michael@0: * All rights reserved. michael@0: * michael@0: * Redistribution and use in source and binary forms, with or without michael@0: * modification, are permitted provided that the following conditions michael@0: * are met: michael@0: * michael@0: * Redistributions of source code must retain the above copyright michael@0: * notice, this list of conditions and the following disclaimer. michael@0: * michael@0: * Redistributions in binary form must reproduce the above michael@0: * copyright notice, this list of conditions and the following michael@0: * disclaimer in the documentation and/or other materials provided michael@0: * with the distribution. michael@0: * michael@0: * Neither the name of the Cisco Systems, Inc. nor the names of its michael@0: * contributors may be used to endorse or promote products derived michael@0: * from this software without specific prior written permission. michael@0: * michael@0: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS michael@0: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT michael@0: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS michael@0: * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE michael@0: * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, michael@0: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES michael@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR michael@0: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) michael@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, michael@0: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) michael@0: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED michael@0: * OF THE POSSIBILITY OF SUCH DAMAGE. michael@0: * michael@0: */ michael@0: michael@0: #ifndef SRTP_PRIV_H michael@0: #define SRTP_PRIV_H michael@0: michael@0: #include "srtp.h" michael@0: #include "rdbx.h" michael@0: #include "rdb.h" michael@0: #include "integers.h" michael@0: michael@0: /* michael@0: * an srtp_hdr_t represents the srtp header michael@0: * michael@0: * in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned michael@0: * michael@0: * (note that this definition follows that of RFC 1889 Appendix A, but michael@0: * is not identical) michael@0: */ michael@0: michael@0: #ifndef WORDS_BIGENDIAN michael@0: michael@0: /* michael@0: * srtp_hdr_t represents an RTP or SRTP header. The bit-fields in michael@0: * this structure should be declared "unsigned int" instead of michael@0: * "unsigned char", but doing so causes the MS compiler to not michael@0: * fully pack the bit fields. michael@0: */ michael@0: michael@0: typedef struct { michael@0: unsigned char cc:4; /* CSRC count */ michael@0: unsigned char x:1; /* header extension flag */ michael@0: unsigned char p:1; /* padding flag */ michael@0: unsigned char version:2; /* protocol version */ michael@0: unsigned char pt:7; /* payload type */ michael@0: unsigned char m:1; /* marker bit */ michael@0: uint16_t seq; /* sequence number */ michael@0: uint32_t ts; /* timestamp */ michael@0: uint32_t ssrc; /* synchronization source */ michael@0: } srtp_hdr_t; michael@0: michael@0: #else /* BIG_ENDIAN */ michael@0: michael@0: typedef struct { michael@0: unsigned char version:2; /* protocol version */ michael@0: unsigned char p:1; /* padding flag */ michael@0: unsigned char x:1; /* header extension flag */ michael@0: unsigned char cc:4; /* CSRC count */ michael@0: unsigned char m:1; /* marker bit */ michael@0: unsigned pt:7; /* payload type */ michael@0: uint16_t seq; /* sequence number */ michael@0: uint32_t ts; /* timestamp */ michael@0: uint32_t ssrc; /* synchronization source */ michael@0: } srtp_hdr_t; michael@0: michael@0: #endif michael@0: michael@0: typedef struct { michael@0: uint16_t profile_specific; /* profile-specific info */ michael@0: uint16_t length; /* number of 32-bit words in extension */ michael@0: } srtp_hdr_xtnd_t; michael@0: michael@0: michael@0: /* michael@0: * srtcp_hdr_t represents a secure rtcp header michael@0: * michael@0: * in this implementation, an srtcp header is assumed to be 32-bit michael@0: * alinged michael@0: */ michael@0: michael@0: #ifndef WORDS_BIGENDIAN michael@0: michael@0: typedef struct { michael@0: unsigned char rc:5; /* reception report count */ michael@0: unsigned char p:1; /* padding flag */ michael@0: unsigned char version:2; /* protocol version */ michael@0: unsigned char pt:8; /* payload type */ michael@0: uint16_t len; /* length */ michael@0: uint32_t ssrc; /* synchronization source */ michael@0: } srtcp_hdr_t; michael@0: michael@0: typedef struct { michael@0: unsigned int index:31; /* srtcp packet index in network order! */ michael@0: unsigned int e:1; /* encrypted? 1=yes */ michael@0: /* optional mikey/etc go here */ michael@0: /* and then the variable-length auth tag */ michael@0: } srtcp_trailer_t; michael@0: michael@0: michael@0: #else /* BIG_ENDIAN */ michael@0: michael@0: typedef struct { michael@0: unsigned char version:2; /* protocol version */ michael@0: unsigned char p:1; /* padding flag */ michael@0: unsigned char rc:5; /* reception report count */ michael@0: unsigned char pt:8; /* payload type */ michael@0: uint16_t len; /* length */ michael@0: uint32_t ssrc; /* synchronization source */ michael@0: } srtcp_hdr_t; michael@0: michael@0: typedef struct { michael@0: unsigned int version:2; /* protocol version */ michael@0: unsigned int p:1; /* padding flag */ michael@0: unsigned int count:5; /* varies by packet type */ michael@0: unsigned int pt:8; /* payload type */ michael@0: uint16_t length; /* len of uint32s of packet less header */ michael@0: } rtcp_common_t; michael@0: michael@0: typedef struct { michael@0: unsigned int e:1; /* encrypted? 1=yes */ michael@0: unsigned int index:31; /* srtcp packet index */ michael@0: /* optional mikey/etc go here */ michael@0: /* and then the variable-length auth tag */ michael@0: } srtcp_trailer_t; michael@0: michael@0: #endif michael@0: michael@0: michael@0: /* michael@0: * the following declarations are libSRTP internal functions michael@0: */ michael@0: michael@0: /* michael@0: * srtp_get_stream(ssrc) returns a pointer to the stream corresponding michael@0: * to ssrc, or NULL if no stream exists for that ssrc michael@0: */ michael@0: michael@0: srtp_stream_t michael@0: srtp_get_stream(srtp_t srtp, uint32_t ssrc); michael@0: michael@0: michael@0: /* michael@0: * srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by michael@0: * deriving all of the needed keys using the KDF and the key k. michael@0: */ michael@0: michael@0: michael@0: err_status_t michael@0: srtp_stream_init_keys(srtp_stream_t srtp, const void *key); michael@0: michael@0: /* michael@0: * srtp_stream_init(s, p) initializes the srtp_stream_t s to michael@0: * use the policy at the location p michael@0: */ michael@0: err_status_t michael@0: srtp_stream_init(srtp_stream_t srtp, michael@0: const srtp_policy_t *p); michael@0: michael@0: michael@0: /* michael@0: * libsrtp internal datatypes michael@0: */ michael@0: michael@0: typedef enum direction_t { michael@0: dir_unknown = 0, michael@0: dir_srtp_sender = 1, michael@0: dir_srtp_receiver = 2 michael@0: } direction_t; michael@0: michael@0: /* michael@0: * an srtp_stream_t has its own SSRC, encryption key, authentication michael@0: * key, sequence number, and replay database michael@0: * michael@0: * note that the keys might not actually be unique, in which case the michael@0: * cipher_t and auth_t pointers will point to the same structures michael@0: */ michael@0: michael@0: typedef struct srtp_stream_ctx_t { michael@0: uint32_t ssrc; michael@0: cipher_t *rtp_cipher; michael@0: auth_t *rtp_auth; michael@0: rdbx_t rtp_rdbx; michael@0: sec_serv_t rtp_services; michael@0: cipher_t *rtcp_cipher; michael@0: auth_t *rtcp_auth; michael@0: rdb_t rtcp_rdb; michael@0: sec_serv_t rtcp_services; michael@0: key_limit_ctx_t *limit; michael@0: direction_t direction; michael@0: int allow_repeat_tx; michael@0: ekt_stream_t ekt; michael@0: struct srtp_stream_ctx_t *next; /* linked list of streams */ michael@0: } srtp_stream_ctx_t; michael@0: michael@0: michael@0: /* michael@0: * an srtp_ctx_t holds a stream list and a service description michael@0: */ michael@0: michael@0: typedef struct srtp_ctx_t { michael@0: srtp_stream_ctx_t *stream_list; /* linked list of streams */ michael@0: srtp_stream_ctx_t *stream_template; /* act as template for other streams */ michael@0: } srtp_ctx_t; michael@0: michael@0: michael@0: michael@0: /* michael@0: * srtp_handle_event(srtp, srtm, evnt) calls the event handling michael@0: * function, if there is one. michael@0: * michael@0: * This macro is not included in the documentation as it is michael@0: * an internal-only function. michael@0: */ michael@0: michael@0: #define srtp_handle_event(srtp, strm, evnt) \ michael@0: if(srtp_event_handler) { \ michael@0: srtp_event_data_t data; \ michael@0: data.session = srtp; \ michael@0: data.stream = strm; \ michael@0: data.event = evnt; \ michael@0: srtp_event_handler(&data); \ michael@0: } michael@0: michael@0: michael@0: #endif /* SRTP_PRIV_H */