blob: 3adcd8d240ca06b8dc42eed55066d417f55c6496 [file] [log] [blame]
/*
Copyright (C) 2011 - 2012 Werner Dittmann
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 CRYPTOCONTEXTCTRL_H
#define CRYPTOCONTEXTCTRL_H
/**
* @file CryptoContextCtrl.h
* @brief The C++ SRTCP implementation
* @ingroup Z_SRTP
* @{
*/
class SrtpSymCrypto;
/**
* The implementation for a SRTCP cryptographic context.
*
* This class holds data and provides functions that implement a
* cryptographic context for SRTCP, Refer to RFC 3711, chapter 3.2 for some
* more detailed information about the SRTCP cryptographic context.
*
* Each SRTCP cryptographic context maintains a RTCP source identified by
* its SSRC. Thus you can independently protect each source inside a RTP
* session.
*
* Key management mechanisms negotiate the parameters for the SRTCP
* cryptographic context, such as master key, key length, authentication
* length and so on. The key management mechanisms are not part of
* SRTCP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
* (RFC6189). After key management negotiated the data the application
* can setup the SRTCP cryptographic context and enable SRTCP processing.
*
* @sa CryptoContext
*
* @author Werner Dittmann <Werner.Dittmann@t-online.de>
*/
class CryptoContextCtrl {
public:
/**
* @brief Constructor for an active SRTCP cryptographic context.
*
* This constructor creates an active SRTCP cryptographic context were
* algorithms are enabled, keys are computed and so on. This SRTCP
* cryptographic context can protect a RTCP SSRC stream.
*
* See the notes in CryptoContext documentation regarding the handling
* of key data.
*
* @param ssrc
* The RTP SSRC that this SRTCP cryptographic context protects.
*
* @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, SrtpAuthenticationSkeinHmac
* </code>.
*
* @param masterKey
* Pointer to the master key for this SRTCP 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 SRTCP uses AES
* based encryption only, then master key length may be 16 or 32
* bytes (128 or 256 bit master key)
*
* @param masterSalt
* SRTCP 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. SRTCP 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 SRTCP 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. SRTCP
* 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. SRTCP 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 SRTCP appends
* to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
*/
CryptoContextCtrl(uint32_t ssrc,
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);
/**
* @brief Destructor.
*
* Cleans the SRTCP cryptographic context.
*/
~CryptoContextCtrl();
/**
* @brief Perform SRTCP encryption.
*
* This method encrypts <em>and</em> decrypts SRTCP payload data. Plain
* data gets encrypted, encrypted data get decrypted.
*
* @param rtp
* The RTP packet that contains the data to encrypt.
*
* @param len
* Length of the RTCP packet
*
* @param index
* The 31 bit SRTCP packet index.
*
* @param ssrc
* The RTCP SSRC data in <em>host</em> order.
*/
void srtcpEncrypt(uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc);
/**
* @brief Compute the authentication tag.
*
* Compute the authentication tag according the the paramters in the
* SRTCP Cryptograhic context.
*
* @param rtp
* The RTCP packet that contains the data to authenticate.
*
* @param len
* Length of the RTCP packet
*
* @param index
* The 31 bit SRTCP index.
*
* @param tag
* Points to a buffer that hold the computed tag. This buffer must
* be able to hold <code>tagLength</code> bytes.
*/
void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag);
/**
* @brief Perform key derivation according to SRTCP 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
* SRTCP cryptograhic context was set up.
*
* This method clears the key data once it was processed by the encryptions'
* set key functions.
*
*/
void deriveSrtcpKeys();
/**
* @brief 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 RTCP 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(uint32_t newSeqNumber);
/**
* @brief Update the SRTCP 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 RTCP packet in host order.
*/
void update(uint32_t newSeqNumber);
/**
* @brief Get the length of the SRTCP authentication tag in bytes.
*
* @return the length of the authentication tag.
*/
inline int32_t getTagLength() const { return tagLength; }
/**
* @brief Get the length of the MKI in bytes.
*
* @return the length of the MKI.
*/
inline int32_t getMkiLength() const { return mkiLength; }
/**
* @brief Get the SSRC of this SRTCP Cryptograhic context.
*
* @return the SSRC.
*/
inline uint32_t getSsrc() const { return ssrcCtx; }
/**
* @brief Get the SRTCP index field of this SRTCP Cryptograhic context.
*
* @return the SRTCP.
*/
uint32_t getSrtcpIndex() const { return srtcpIndex; }
/**
* @brief Set the SRTCP index field of this SRTCP Cryptograhic context.
*
* @param index the new SRTCP index value.
*
*/
void setSrtcpIndex(uint32_t index) { srtcpIndex = index; }
/**
* @brief Set the start (base) number to compute the PRF labels.
*
* Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
* CryptoContextCtrl computes the labes as follows:
*
* - labelBase + 0 -> encryption label
* - labelBase + 1 -> authentication label
* - labelBase + 2 -> salting key label
*
* The CryptoContextCtrl constructor initializes CryptoContextCtrl#labelBase
* with 3 to comply with RFC 3711 label values.
*
* Applications may set #labelBase to other values to use CryptoContextCtrl
* for other purposes.
*/
void setLabelbase(uint8_t base) { labelBase = base; }
/**
* @brief Derive a new Crypto Context for use with a new SSRC
*
* This method returns a new CryptoContextCtrl initialized with the data
* of this crypto context. The application can use this CryptoContextCtrl
* instance to encrypt / decrypt a new stream (Synchronization source) inside
* one RTCP session.
*
* Before the application can use this crypto context it must call deriveSrtcpKeys().
*
* @param ssrc
* The SSRC for this context
*
* @return
* a new CryptoContextCtrl with all relevant data set.
*/
CryptoContextCtrl* newCryptoContextForSSRC(uint32_t ssrc);
private:
uint32_t ssrcCtx;
bool using_mki;
uint32_t mkiLength;
uint8_t* mki;
uint32_t s_l;
/* bitmask for replay check */
uint64_t replay_window;
uint8_t* master_key;
uint32_t master_key_length;
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;
uint32_t srtcpIndex;
uint8_t labelBase;
void* macCtx;
SrtpSymCrypto* cipher;
SrtpSymCrypto* f8Cipher;
};
/**
* @}
*/
#endif