1 /* 2 * libjingle 3 * Copyright 2009, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_SESSION_PHONE_SRTPFILTER_H_ 29 #define TALK_SESSION_PHONE_SRTPFILTER_H_ 30 31 #include <list> 32 #include <string> 33 #include <vector> 34 #include "talk/base/basictypes.h" 35 #include "talk/session/phone/cryptoparams.h" 36 #include "talk/p2p/base/sessiondescription.h" 37 38 // Forward declaration to avoid pulling in libsrtp headers here 39 struct srtp_event_data_t; 40 struct srtp_ctx_t; 41 typedef srtp_ctx_t* srtp_t; 42 struct srtp_policy_t; 43 44 namespace cricket { 45 46 // Cipher suite to use for SRTP. Typically a 80-bit HMAC will be used, except 47 // in applications (voice) where the additional bandwidth may be significant. 48 // A 80-bit HMAC is always used for SRTCP. 49 extern const std::string& CS_DEFAULT; 50 // 128-bit AES with 80-bit SHA-1 HMAC. 51 extern const std::string CS_AES_CM_128_HMAC_SHA1_80; 52 // 128-bit AES with 32-bit SHA-1 HMAC. 53 extern const std::string CS_AES_CM_128_HMAC_SHA1_32; 54 // Key is 128 bits and salt is 112 bits == 30 bytes. B64 bloat => 40 bytes. 55 extern const int SRTP_MASTER_KEY_BASE64_LEN; 56 57 // Class that wraps a libSRTP session. Used internally by SrtpFilter, below. 58 class SrtpSession { 59 public: 60 SrtpSession(); 61 ~SrtpSession(); 62 63 // Configures the session for sending data using the specified 64 // cipher-suite and key. Receiving must be done by a separate session. 65 bool SetSend(const std::string& cs, const uint8* key, int len); 66 // Configures the session for receiving data using the specified 67 // cipher-suite and key. Sending must be done by a separate session. 68 bool SetRecv(const std::string& cs, const uint8* key, int len); 69 70 // Encrypts/signs an individual RTP/RTCP packet, in-place. 71 // If an HMAC is used, this will increase the packet size. 72 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); 73 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); 74 // Decrypts/verifies an invidiual RTP/RTCP packet. 75 // If an HMAC is used, this will decrease the packet size. 76 bool UnprotectRtp(void* data, int in_len, int* out_len); 77 bool UnprotectRtcp(void* data, int in_len, int* out_len); 78 79 private: 80 bool SetKey(int type, const std::string& cs, const uint8* key, int len); 81 static bool Init(); 82 void HandleEvent(const srtp_event_data_t* ev); 83 static void HandleEventThunk(srtp_event_data_t* ev); 84 85 srtp_t session_; 86 int rtp_auth_tag_len_; 87 int rtcp_auth_tag_len_; 88 static bool inited_; 89 static std::list<SrtpSession*> sessions_; 90 }; 91 92 // Class to transform SRTP to/from RTP. 93 // Initialize by calling SetSend with the local security params, then call 94 // SetRecv once the remote security params are received. At that point 95 // Protect/UnprotectRt(c)p can be called to encrypt/decrypt data. 96 // TODO: Figure out concurrency policy for SrtpFilter. 97 class SrtpFilter { 98 public: 99 SrtpFilter(); 100 ~SrtpFilter(); 101 102 // Whether the filter is active (i.e. crypto has been properly negotiated). 103 bool IsActive() const; 104 105 // Indicates which crypto algorithms and keys were contained in the offer. 106 // offer_params should contain a list of available parameters to use, or none, 107 // if crypto is not desired. This must be called before SetAnswer. 108 bool SetOffer(const std::vector<CryptoParams>& offer_params, 109 ContentSource source); 110 // Indicates which crypto algorithms and keys were contained in the answer. 111 // answer_params should contain the negotiated parameters, which may be none, 112 // if crypto was not desired or could not be negotiated (and not required). 113 // This must be called after SetOffer. If crypto negotiation completes 114 // successfully, this will advance the filter to the active state. 115 bool SetAnswer(const std::vector<CryptoParams>& answer_params, 116 ContentSource source); 117 118 // Encrypts/signs an individual RTP/RTCP packet, in-place. 119 // If an HMAC is used, this will increase the packet size. 120 bool ProtectRtp(void* data, int in_len, int max_len, int* out_len); 121 bool ProtectRtcp(void* data, int in_len, int max_len, int* out_len); 122 // Decrypts/verifies an invidiual RTP/RTCP packet. 123 // If an HMAC is used, this will decrease the packet size. 124 bool UnprotectRtp(void* data, int in_len, int* out_len); 125 bool UnprotectRtcp(void* data, int in_len, int* out_len); 126 127 protected: 128 bool StoreParams(const std::vector<CryptoParams>& offer_params, 129 ContentSource source); 130 bool NegotiateParams(const std::vector<CryptoParams>& answer_params, 131 CryptoParams* selected_params); 132 bool ApplyParams(const CryptoParams& send_params, 133 const CryptoParams& recv_params); 134 bool ResetParams(); 135 static bool ParseKeyParams(const std::string& params, uint8* key, int len); 136 137 private: 138 enum State { ST_INIT, ST_SENTOFFER, ST_RECEIVEDOFFER, ST_ACTIVE }; 139 State state_; 140 std::vector<CryptoParams> offer_params_; 141 SrtpSession send_session_; 142 SrtpSession recv_session_; 143 }; 144 145 } // namespace cricket 146 147 #endif // TALK_SESSION_PHONE_SRTPFILTER_H_ 148