/* 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 #include 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 * @author Erik Eliasson * @author Johan Bilien * @author Joachim Orrblad * @author Werner Dittmann */ 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 * SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8 * . 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 * SrtpEncryptionNull, SrtpAuthenticationSha1Hmac. 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 masterKeyLength 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 and 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 guessIndex * method. * * @param ssrc * The RTP SSRC data in host 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 tagLength 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 guessIndex * 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 true if no replay, false 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 deriveSrtpKeys 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: */