| /* |
| Copyright (C) 2004-2006 the Minisip Team |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| |
| |
| #ifndef CRYPTOCONTEXT_H |
| #define CRYPTOCONTEXT_H |
| |
| /** |
| * @file CryptoContext.h |
| * @brief The C++ SRTP implementation |
| * @ingroup Z_SRTP |
| * @{ |
| */ |
| |
| #define REPLAY_WINDOW_SIZE 64 |
| |
| const int SrtpAuthenticationNull = 0; |
| const int SrtpAuthenticationSha1Hmac = 1; |
| const int SrtpAuthenticationSkeinHmac = 2; |
| |
| const int SrtpEncryptionNull = 0; |
| const int SrtpEncryptionAESCM = 1; |
| const int SrtpEncryptionAESF8 = 2; |
| const int SrtpEncryptionTWOCM = 3; |
| const int SrtpEncryptionTWOF8 = 4; |
| |
| #ifndef CRYPTOCONTEXTCTRL_H |
| |
| #include <stdint.h> |
| #include <crypto/SrtpSymCrypto.h> |
| |
| class SrtpSymCrypto; |
| |
| /** |
| * The implementation for a SRTP cryptographic context. |
| * |
| * This class holds data and provides functions that implement a |
| * cryptographic context for SRTP, Refer to RFC 3711, chapter 3.2 for some |
| * more detailed information about the SRTP cryptographic context. |
| * |
| * Each SRTP cryptographic context maintains a RTP source identified by |
| * its SSRC. Thus you can independently protect each source inside a RTP |
| * session. |
| * |
| * Key management mechanisms negotiate the parameters for the SRTP |
| * cryptographic context, such as master key, key length, authentication |
| * length and so on. The key management mechanisms are not part of |
| * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol |
| * (draft-zimmermann-avt-zrtp-01). After key management negotiated the |
| * data the application can setup the SRTP cryptographic context and |
| * enable SRTP processing. |
| * |
| * Currently this implementation supports RTP only, not RTCP. |
| * |
| * @author Israel Abad <i_abad@terra.es> |
| * @author Erik Eliasson <eliasson@it.kth.se> |
| * @author Johan Bilien <jobi@via.ecp.fr> |
| * @author Joachim Orrblad <joachim@orrblad.com> |
| * @author Werner Dittmann <Werner.Dittmann@t-online.de> |
| */ |
| |
| class CryptoContext { |
| public: |
| /** |
| * Constructor for an active SRTP cryptographic context. |
| * |
| * This constructor creates an active SRTP cryptographic context were |
| * algorithms are enabled, keys are computed and so on. This SRTP |
| * cryptographic context can protect a RTP SSRC stream. |
| * |
| * @param ssrc |
| * The RTP SSRC that this SRTP cryptographic context protects. |
| * |
| * @param roc |
| * The initial Roll-Over-Counter according to RFC 3711. These are the |
| * upper 32 bit of the overall 48 bit SRTP packet index. Refer to |
| * chapter 3.2.1 of the RFC. |
| * |
| * @param keyDerivRate |
| * The key derivation rate defines when to recompute the SRTP session |
| * keys. Refer to chapter 4.3.1 in the RFC. |
| * |
| * @param ealg |
| * The encryption algorithm to use. Possible values are <code> |
| * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8 |
| * </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2 |
| * for AES F8 mode. |
| * |
| * @param aalg |
| * The authentication algorithm to use. Possible values are <code> |
| * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only |
| * active algorithm here is SHA1 HMAC, a SHA1 based hashed message |
| * authentication code as defined in RFC 2104. |
| * |
| * @param masterKey |
| * Pointer to the master key for this SRTP cryptographic context. |
| * Must point to <code>masterKeyLength</code> bytes. Refer to chapter |
| * 3.2.1 of the RFC about the role of the master key. |
| * |
| * @param masterKeyLength |
| * The length in bytes of the master key in bytes. The length must |
| * match the selected encryption algorithm. Because SRTP uses AES |
| * based encryption only, then master key length may be 16 or 32 |
| * bytes (128 or 256 bit master key) |
| * |
| * @param masterSalt |
| * SRTP uses the master salt to computer the initialization vector |
| * that in turn is input to compute the session key, session |
| * authentication key and the session salt. |
| * |
| * @param masterSaltLength |
| * The length in bytes of the master salt data in bytes. SRTP uses |
| * AES as encryption algorithm. AES encrypts 16 byte blocks |
| * (independent of the key length). According to RFC3711 the standard |
| * value for the master salt length should be 112 bit (14 bytes). |
| * |
| * @param ekeyl |
| * The length in bytes of the session encryption key that SRTP shall |
| * compute and use. Usually the same length as for the master key |
| * length. But you may use a different length as well. Be carefull |
| * that the key management mechanisms supports different key lengths. |
| * |
| * @param akeyl |
| * The length in bytes of the session authentication key. SRTP |
| * computes this key and uses it as input to the authentication |
| * algorithm. |
| * The standard value is 160 bits (20 bytes). |
| * |
| * @param skeyl |
| * The length in bytes of the session salt. SRTP computes this salt |
| * key and uses it as input during encryption. The length usually |
| * is the same as the master salt length. |
| * |
| * @param tagLength |
| * The length is bytes of the authentication tag that SRTP appends |
| * to the RTP packet. Refer to chapter 4.2. in the RFC 3711. |
| */ |
| CryptoContext( uint32_t ssrc, int32_t roc, |
| int64_t keyDerivRate, |
| const int32_t ealg, |
| const int32_t aalg, |
| uint8_t* masterKey, |
| int32_t masterKeyLength, |
| uint8_t* masterSalt, |
| int32_t masterSaltLength, |
| int32_t ekeyl, |
| int32_t akeyl, |
| int32_t skeyl, |
| int32_t tagLength ); |
| /** |
| * Destructor. |
| * |
| * Cleans the SRTP cryptographic context. |
| */ |
| ~CryptoContext(); |
| |
| /** |
| * Set the Roll-Over-Counter. |
| * |
| * Ths method sets the upper 32 bit of the 48 bit SRTP packet index |
| * (the roll-over-part) |
| * |
| * @param r |
| * The roll-over-counter |
| */ |
| inline void |
| setRoc(uint32_t r) |
| { |
| roc = r; |
| } |
| |
| /** |
| * Get the Roll-Over-Counter. |
| * |
| * Ths method get the upper 32 bit of the 48 bit SRTP packet index |
| * (the roll-over-part) |
| * |
| * @return The roll-over-counter |
| */ |
| inline uint32_t |
| getRoc() const |
| { |
| return roc; |
| } |
| |
| /** |
| * Perform SRTP encryption. |
| * |
| * This method encrypts <em>and</em> decrypts SRTP payload data. Plain |
| * data gets encrypted, encrypted data get decrypted. |
| * |
| * @param pkt |
| * Pointer to RTP packet buffer, used for F8. |
| * |
| * @param payload |
| * The data to encrypt. |
| * |
| * @param paylen |
| * Length of payload. |
| * |
| * @param index |
| * The 48 bit SRTP packet index. See the <code>guessIndex</code> |
| * method. |
| * |
| * @param ssrc |
| * The RTP SSRC data in <em>host</em> order. |
| */ |
| void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc ); |
| |
| /** |
| * Compute the authentication tag. |
| * |
| * Compute the authentication tag according the the paramters in the |
| * SRTP Cryptograhic context. |
| * |
| * @param pkt |
| * Pointer to RTP packet buffer that contains the data to authenticate. |
| * |
| * @param pktlen |
| * Length of the RTP packet buffer |
| * |
| * @param roc |
| * The 32 bit SRTP roll-over-counter. |
| * |
| * @param tag |
| * Points to a buffer that hold the computed tag. This buffer must |
| * be able to hold <code>tagLength</code> bytes. |
| */ |
| void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag ); |
| |
| /** |
| * Perform key derivation according to SRTP specification |
| * |
| * This method computes the session key, session authentication key and the |
| * session salt key. This method must be called at least once after the |
| * SRTP Cryptograhic context was set up. |
| * |
| * @param index |
| * The 48 bit SRTP packet index. See the <code>guessIndex</code> |
| * method. |
| */ |
| void deriveSrtpKeys(uint64_t index); |
| |
| /** |
| * Compute (guess) the new SRTP index based on the sequence number of |
| * a received RTP packet. |
| * |
| * The method uses the algorithm show in RFC3711, Appendix A, to compute |
| * the new index. |
| * |
| * @param newSeqNumber |
| * The sequence number of the received RTP packet in host order. |
| * |
| * @return The new SRTP packet index |
| */ |
| uint64_t guessIndex(uint16_t newSeqNumber); |
| |
| /** |
| * Check for packet replay. |
| * |
| * The method check if a received packet is either to old or was already |
| * received. |
| * |
| * The method supports a 64 packet history relative the the given |
| * sequence number. |
| * |
| * @param newSeqNumber |
| * The sequence number of the received RTP packet in host order. |
| * |
| * @return <code>true</code> if no replay, <code>false</code> if packet |
| * is too old ar was already received. |
| */ |
| bool checkReplay(uint16_t newSeqNumber); |
| |
| /** |
| * Update the SRTP packet index. |
| * |
| * Call this method after all checks were successful. See chapter |
| * 3.3.1 in the RFC when to update the ROC and ROC processing. |
| * |
| * @param newSeqNumber |
| * The sequence number of the received RTP packet in host order. |
| */ |
| void update( uint16_t newSeqNumber ); |
| |
| /** |
| * Get the length of the SRTP authentication tag in bytes. |
| * |
| * @return the length of the authentication tag. |
| */ |
| inline int32_t |
| getTagLength() const |
| { |
| return tagLength; |
| } |
| |
| |
| /** |
| * Get the length of the MKI in bytes. |
| * |
| * @return the length of the MKI. |
| */ |
| inline int32_t |
| getMkiLength() const |
| { |
| return mkiLength; |
| } |
| |
| /** |
| * Get the SSRC of this SRTP Cryptograhic context. |
| * |
| * @return the SSRC. |
| */ |
| inline uint32_t |
| getSsrc() const |
| { |
| return ssrcCtx; |
| } |
| |
| /** |
| * Derive a new Crypto Context for use with a new SSRC |
| * |
| * This method returns a new Crypto Context initialized with the data |
| * of this crypto context. Replacing the SSRC, Roll-over-Counter, and |
| * the key derivation rate the application cab use this Crypto Context |
| * to encrypt / decrypt a new stream (Synchronization source) inside |
| * one RTP session. |
| * |
| * Before the application can use this crypto context it must call |
| * the <code>deriveSrtpKeys</code> method. |
| * |
| * @param ssrc |
| * The SSRC for this context |
| * @param roc |
| * The Roll-Over-Counter for this context |
| * @param keyDerivRate |
| * The key derivation rate for this context |
| * @return |
| * a new CryptoContext with all relevant data set. |
| */ |
| |
| CryptoContext* newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate); |
| |
| private: |
| |
| uint32_t ssrcCtx; |
| bool using_mki; |
| uint32_t mkiLength; |
| uint8_t* mki; |
| |
| uint32_t roc; |
| uint32_t guessed_roc; |
| uint16_t s_l; |
| int64_t key_deriv_rate; |
| |
| /* bitmask for replay check */ |
| uint64_t replay_window; |
| |
| uint8_t* master_key; |
| uint32_t master_key_length; |
| uint32_t master_key_srtp_use_nb; |
| uint32_t master_key_srtcp_use_nb; |
| uint8_t* master_salt; |
| uint32_t master_salt_length; |
| |
| /* Session Encryption, Authentication keys, Salt */ |
| int32_t n_e; |
| uint8_t* k_e; |
| int32_t n_a; |
| uint8_t* k_a; |
| int32_t n_s; |
| uint8_t* k_s; |
| |
| int32_t ealg; |
| int32_t aalg; |
| int32_t ekeyl; |
| int32_t akeyl; |
| int32_t skeyl; |
| int32_t tagLength; |
| bool seqNumSet; |
| |
| void* macCtx; |
| |
| SrtpSymCrypto* cipher; |
| SrtpSymCrypto* f8Cipher; |
| }; |
| |
| #endif |
| |
| /** |
| * @} |
| */ |
| #endif |
| |
| /** EMACS ** |
| * Local variables: |
| * mode: c++ |
| * c-default-style: ellemtel |
| * c-basic-offset: 4 |
| * End: |
| */ |
| |